我有一个简单的示例脚本构造,它在python中使用multiprocessing
定义了三个独立的进程。我的目标是让一个父线程生成两个较小的线程来收集和处理数据。
目前,我的实现如下:
from Queue import Queue,Empty
from multiprocessing import Process
import time
import hashlib
class FillQueue(Process):
def __init__(self,q):
Process.__init__(self)
self.q = q
def run(self):
i = 0
while i is not 5:
print 'putting'
self.q.put('foo')
i+=1
self.q.put('|STOP|')
class ConsumeQueue(Process):
def __init__(self,q):
Process.__init__(self)
self.q = q
def run(self):
print 'Consume'
while True:
try:
value = self.q.get(False)
print value
if value == '|STOP|':
print 'done'
break;
except Empty:
print 'Nothing to process atm'
class Ripper(Process):
q = Queue()
def __init__(self):
self.fq = FillQueue(self.q)
self.cq = ConsumeQueue(self.q)
self.fq.daemon = True
self.cq.daemon = True
def run(self):
try:
self.fq.start()
self.cq.start()
except KeyboardInterrupt:
print 'exit'
if __name__ == '__main__':
r = Ripper()
r.start()
当前运行时,CLI上脚本的输出如下所示:
putting
putting
putting
putting
putting
Consume
foo
foo
foo
foo
foo
|STOP|
done
显然,我启动两个线程的方式是阻塞,因为消费者甚至没有开始处理队列中的项目,直到填充程序完成添加项目。
我应该如何重写这个以使两个线程立即开始而不是阻塞,因此消费者只需传递给Empty
除了块,而没有工作要处理,但是当它收到停止时将完全退出消息?
编辑:拼写错误,将start
和run
方法混为一谈
答案 0 :(得分:3)
我认为你的程序运行正常。 CPU在短时间内一次只处理一件事。但是,将所有内容放入队列所需的时间非常短。所以填充物没有理由不能在一个时间片内完成。
如果你在填充物中添加了一些延迟,我认为你应该看到它实际上按预期工作。
答案 1 :(得分:3)
您似乎正在使用multiprocessing.Process启动多个进程。
但是,您使用的Queue.Queue只是线程安全的,并不是为多个进程设计的。
shevek的答案也是有效的,但作为一个开始,你应该用multiprocessing.Queue替换Queue.Queue。
答案 2 :(得分:3)
试试这个:
from Queue import Empty
from multiprocessing import Process, Queue
import time
import hashlib
class FillQueue(object):
def __init__(self, q):
self.q = q
def run(self):
i = 0
while i < 5:
print 'putting'
self.q.put('foo %d' % i )
i+=1
time.sleep(.5)
self.q.put('|STOP|')
class ConsumeQueue(object):
def __init__(self, q):
self.q = q
def run(self):
while True:
try:
value = self.q.get(False)
print value
if value == '|STOP|':
print 'done'
break;
except Empty:
print 'Nothing to process atm'
time.sleep(.2)
if __name__ == '__main__':
q = Queue()
f = FillQueue(q)
c = ConsumeQueue(q)
p1 = Process(target=f.run)
p1.start()
p2 = Process(target=c.run)
p2.start()
p1.join()
p2.join()