Skip to main content
 首页 » 编程设计

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

2024年10月25日30freeliver54

我即将开始使用 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 中是否是不可能的,或者我是不是看错了这个问题?

请您参考如下方法:

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

您还可以通过使用 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