在多线程Python中使用队列,将队列作为参考传递给子函数

时间:2015-05-23 16:39:57

标签: python multithreading

我即将开始使用python。目标是多线程处理不同的任务并使用队列在任务之间进行通信。为了清楚起见,我希望能够将队列传递给子功能,从而从那里向队列发送信息。所以类似的事情如下:

from queue import Queue
from threading import Thread
import copy

# Object that signals shutdown
_sentinel = object()

# increment function
def increment(i, out_q):
    i += 1
    print(i)
    out_q.put(i)
    return

# A thread that produces data
def producer(out_q):
    i = 0
    while True:
        # Produce some data
        increment( i , out_q)

        if i > 5:
            out_q.put(_sentinel)
            break

# A thread that consumes data
def consumer(in_q):
    while True:
        # Get some data
        data = in_q.get()
        # Process the data

        # Check for termination
        if data is _sentinel:
            in_q.put(_sentinel)
            break


# Create the shared queue and launch both threads
q = Queue()
t1 = Thread(target=consumer, args=(q,))
t2 = Thread(target=producer, args=(q,))
t1.start()
t2.start()

# Wait for all produced items to be consumed
q.join()

目前输出是一行0,我希望它是数字1到6.我已经阅读了在python中传递引用的难度,但是想澄清一下这是不可能在python或我错误地看待这个问题吗?

1 个答案:

答案 0 :(得分:2)

问题与队列的传递方式无关;你这样做了。问题实际上与您尝试增加i的方式有关。因为python are passed by assignment中的变量,您必须实际将递增的值i返回给调用者,以使您在increment内所做的更改生效。否则,您只需重新绑定i内的局部变量increment,然后i完成时increment被丢弃。

您还可以使用iter内置函数以及for循环来简化您的使用方法,从队列中消耗,直到达到_sentinel,而不是而不是while True循环:

from queue import Queue
from threading import Thread
import copy

# Object that signals shutdown
_sentinel = object()

# increment function
def increment(i):
    i += 1
    return i

# A thread that produces data
def producer(out_q):
    i = 0
    while True:
        # Produce some data
        i = increment( i )
        print(i)
        out_q.put(i)
        if i > 5:
            out_q.put(_sentinel)
            break

# A thread that consumes data
def consumer(in_q):
    for data in iter(in_q.get, _sentinel):
        # Process the data
        pass


# Create the shared queue and launch both threads
q = Queue()
t1 = Thread(target=consumer, args=(q,))
t2 = Thread(target=producer, args=(q,))
t1.start()
t2.start()

输出:

1
2
3
4
5
6