Python - 启动两个进程无限期运行

时间:2012-10-02 19:31:06

标签: python multithreading multiprocessing

我有一个简单的示例脚本构造,它在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除了块,而没有工作要处理,但是当它收到停止时将完全退出消息?

编辑:拼写错误,将startrun方法混为一谈

3 个答案:

答案 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()