1 from multiprocessing import Pool, Manager
2
3
4 def test(num):
5 queue.put(num)
6
7
8 queue = Manager().Queue()
9 pool = Pool(5)
10
11 for i in range(30):
12 pool.apply_async(test, (i, ))
13
14 pool.close()
15 pool.join()
16
17 print(queue.qsize())
上面的代码输出为30。但是,如果将第8行与第9行交换(请参见下面的代码),则输出将为0。那么有人知道为什么吗?谢谢!
1 from multiprocessing import Pool, Manager
2
3
4 def test(num):
5 queue.put(num)
6
7
8 pool = Pool(5)
9 queue = Manager().Queue()
10
11 for i in range(30):
12 pool.apply_async(test, (i, ))
13
14 pool.close()
15 pool.join()
16
17 print(queue.qsize())
from multiprocessing import Process, Queue
def test():
queue.put(1)
p = Process(target=test)
queue = Queue()
p.start()
p.join()
print(queue.qsize())
输出为1,这意味着子进程将数字放入父进程创建的队列中。正确吗?
答案 0 :(得分:1)
我假设您使用的是基于Unix的操作系统,因为在NT上您的逻辑很可能会中断。
要了解会发生什么,我们需要深入研究multiprocessing
内部。在Unix上,创建新进程时,将使用fork
原语。分叉时,父进程继续执行,子进程作为父进程的精确副本启动。
Python倾向于在multiprocessing
模块中隐藏很多东西(我特别不喜欢),并且导致很多误解。按照您的逻辑,创建fork
时会发生Pool
(第一个示例中的第9行,第二个示例中的第8行)。
在第一个示例中,子级继承父级创建的相同queue
对象。因此,由于他们共享同一频道,因此他们成功地进行了通信。
在第二个示例中,父级和子级创建了自己独立的queue
对象,它们是完全独立的。当孩子将元素放在queue
中时,它会将它放在自己的元素中,任何人都不会共享。
在第三个也是最后一个示例中,创建一个Process
对象,然后创建一个Queue
,然后在该过程中调用start
。猜猜fork
何时发生?当您调用start
而不是在创建Process
对象时。这就是queue
成功共享的原因。这就是我说multiprocessing
API有点误导的意思。