我有一个奇怪的使用python进行队列处理的情况。让我先描述一下:
问题是:对于队列处理器,队列始终为空。让我用一些代码说明问题:
import threading as t
import time
import sys
from multiprocessing import Process
if sys.version_info.major is 2:
import Queue as queue
else:
import queue
class ExampleRecorder:
queue = queue.Queue()
def run(self):
self.thread = t.Thread(target=self.start_processor)
self.thread.daemon = True
self.thread.start()
def start_processor(self):
while 1:
print("PROCESSOR! QUEUE ID: {}. QUEUE SIZE: {}. IS EMPTY: {}".format(id(self.queue), self.queue.qsize(), self.queue.empty()))
time.sleep(1)
def push_message(self, span):
self.queue.put(span)
print("RECORDER! QUEUE ID: {}. QUEUE SIZE: {}".format(id(self.queue), self.queue.qsize()))
er = ExampleRecorder()
er.run()
def producer():
while 1:
print("Adding an item")
er.push_message("foo")
time.sleep(1)
proc = Process(target=producer)
proc.start()
脚本的示例输出为:
$ python3 model.py
PROCESSOR! QUEUE ID: <queue.Queue object at 0x1095f9b70>. QUEUE SIZE: 0. IS EMPTY: True
Adding an item
RECORDER! QUEUE ID: <queue.Queue object at 0x1095f9b70>. QUEUE SIZE: 1
PROCESSOR! QUEUE ID: <queue.Queue object at 0x1095f9b70>. QUEUE SIZE: 0. IS EMPTY: True
Adding an item
RECORDER! QUEUE ID: <queue.Queue object at 0x1095f9b70>. QUEUE SIZE: 2
PROCESSOR! QUEUE ID: <queue.Queue object at 0x1095f9b70>. QUEUE SIZE: 0. IS EMPTY: True
如您所见,队列接收对象并增长,但对于处理器,它始终为空。那里可能出现什么问题?在一个进程中的线程中处理共享队列是否有些棘手?
P.S。检查Python 2.7.12和3.5.2
答案 0 :(得分:2)
Queue.Queue
仅适用于同一个流程,它与线程一起使用,而不是与单独的流程一起使用。
您需要一个multiprocessing.Queue
实例来进行进程间通信,但您还必须重新构建代码以将队列实例明确传递给producer
。就像现在一样,在新进程中评估ExampleRecorder
定义时,每个生成器都会创建一个不同的实例。
注意:使用您编写的代码,所有ExampleRecorder
个实例(同一进程中的 )共享同一个队列!你确定这是你想要的吗?
通过在queue
块中定义class ...
,queue
是类的属性,而不是其实例。这与在queue
中定义__init__()
非常不同。用一个更简单的例子:
from queue import Queue
class SampleClass:
queue = Queue()
class AnotherSample:
def __init__(self):
self.queue = Queue()
inst1 = SampleClass()
inst2 = SampleClass()
inst3 = AnotherSample()
inst4 = AnotherSample()
如果我们测试queue
属性,我们会看到差异:( is
运算符测试两个变量是否是同一对象的别名)
inst1.queue is inst2.queue
Out[8]: True
inst3.queue is inst4.queue
Out[9]: False