python-3.x 为什么不能在pool模块中传递queue作为参数?

vngu2lb8  于 2023-06-07  发布在  Python
关注(0)|答案(2)|浏览(207)
vim  mp_without_queue.py
from multiprocessing import Pool
n = 3 
def hello(i):
    print('hello')
    time.sleep(1)

pool = Pool(processes = 2)
for i in range(n):
    pool.apply_async(hello,args=(i,))
pool.close()
pool.join()

我创建了两个进程并添加了三个任务(调用hello函数3次)。

python3 mp_without_queue.py
hello
hello
hello

它工作正常。现在我只是在参数中添加队列,在传递queue的调用函数中不做任何事情。

vim  mp_with_queue.py
from multiprocessing import Pool,Queue
q = Queue()
n = 3 
def hello(i,q):
    print('hello')
    time.sleep(1)

pool = Pool(processes = 2)
for i in range(n):
    pool.apply_async(hello,args=(i,q))
pool.close()
pool.join()

执行的时候什么也得不到。

python3 mp_with_queue.py
#nothing as output

为什么不能在pool模块中传递queue作为参数?

yacmzcpb

yacmzcpb1#

当你把queue传递给函数本身时,它会被复制,并且不能访问原始对象。你需要用initargs将它传递给初始化器,并在每个进程中在initializer中设置一个全局变量。在这种情况下,您的进程将可以访问原始对象- Queue。

from multiprocessing import Pool, Queue
import time

queue: Queue

def init(q):
    global queue
    queue = q

def hello(i):
    print('hello')
    time.sleep(1)
    queue.put(i)

if __name__ == '__main__':
    q = Queue()

    n = 3

    pool = Pool(processes=2, initializer=init, initargs=(q,))
    for i in range(n):
        pool.apply_async(hello, args=(i,))

    pool.close()
    pool.join()

    while not q.empty():
        print(q.get())

下面是输出:

hello
hello
hello
1
0
2
njthzxwz

njthzxwz2#

Queue被设计为默认在所有进程中共享,因此无需将其传递到函数中,可以直接调用。

vim mp_pool.py
from multiprocessing import Pool, Queue
import time

def hello(i):
    print('hello')
    time.sleep(1)
    q.put(i)

if __name__ == '__main__':
    q = Queue()
    n = 5
    pool = Pool(processes=2)
    for i in range(n):
        pool.apply_async(hello, args=(i,))

    pool.close()
    pool.join()
    while not q.empty():
        print(q.get())

使用python3 mp_pool.py运行它:

hello
hello
hello
hello
hello
1
0
3
2
4

结论:将队列示例传入函数会导致错误,直接在所有子进程和父进程中使用。

相关问题