【问题标题】:One thread writing to queue, one thread reading一个线程写入队列,一个线程读取
【发布时间】:2015-11-02 23:48:57
【问题描述】:

我试图让一个线程将项目添加到队列中,并让主线程将它们拉出。我正在尝试的方法在阅读多处理文档后不起作用。我究竟做错了什么?谢谢。

import time
from multiprocessing import Process, Queue

def append_to_queue(q, t=1):
    n = 0
    while True:
        q.put(n)
        n += 1
        time.sleep(t)

def print_queue(q, t=0.5):
    while True:
        print q.get()
        time.sleep(t)

def main(t1, t2, delay=1):
    q = Queue()
    p = Process(target=append_to_queue, args=(q, t1,))
    p.start()
    time.sleep(delay)
    print_queue(q, t2)
    p.join()

main(1, 0.5, delay=1)

【问题讨论】:

  • 您的代码对我有用,因为它每秒打印出一个递增的数字。你是什​​么意思它不起作用?
  • 有趣的是,我第一次尝试在编写脚本之前在 ipython 中写出东西,它咬了我,tl;dr,我在 windows 上工作,你需要在 windows 上编写多处理。 freeze_support() 在模块级别。
  • 骑自行车时如何摆脱困境?

标签: python windows queue multiprocessing python-multiprocessing


【解决方案1】:
  1. 您使用的是进程而不是线程
  2. 您实际上使用了一个生产流程,但您在主流程中只消耗一次。我想你想要一个消费过程。

这是一个演示:

import time
from multiprocessing import Process, Queue, Event

def append_to_queue(t, q, stopnow):
    n = 0
    while not stopnow.is_set():
        q.put(n)
        n += 1
        time.sleep(t)
    q.put("producer done") # consumer will print this

def print_from_queue(t, q, stopnow):
    while not stopnow.is_set():
        print q.get()
        time.sleep(t)
    # drain queue
    for msg in xrange(q.qsize()):
        print msg
    print "consumer done"

def main(t1, t2):
    # @eryksun:
    # Because windows doesn't fork - the Queue
    # and Event can't be inherited from the main process.
    # Create them in main and pass them in the args tuple.
    q = Queue()
    stopnow = Event()
    producer = Process(target=append_to_queue, args=(t1, q, stopnow))
    producer.start()
    consumer = Process(target=print_from_queue, args=(t2, q, stopnow,))
    consumer.start()
    time.sleep(5)
    stopnow.set()
    producer.join()
    consumer.join()

# @eryksun:
# Windows doesn't fork, so you need to use if __name__ == '__main__'
# to guard calling main
if "__main__" == __name__:
    main(1, 0.5)

【讨论】:

  • Windows 没有分叉,所以你需要使用if __name__ == '__main__' 来保护调用main。也因为没有分叉,QueueEvent 不能从主进程继承。在main 中创建它们并在args 元组中传递它们。
  • @eryksun 现在好点了吗?已应用对 windows 的更改。
最近更新 更多