【问题标题】:the position between Pool object and Manager object in multiprocessing module多处理模块中 Pool 对象和 Manager 对象之间的位置
【发布时间】:2018-12-26 04:23:16
【问题描述】:
 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,表示子进程将数字放入父进程创建的队列中。对吗?

【问题讨论】:

  • 请去掉代码sn-ps旁边的行号。它们使人们很难复制粘贴您的代码进行尝试。

标签: python python-3.x queue multiprocessing pool


【解决方案1】:

我假设您使用的是基于 Unix 的操作系统,因为您的逻辑很可能会中断。

要了解会发生什么,我们需要深入了解multiprocessing 的内部结构。在 Unix 上,当创建一个新进程时,使用 fork 原语。当一个进程分叉时,父进程继续执行,子进程作为父进程的精确副本开始。

Python 倾向于在multiprocessing 模块中隐藏很多东西(我特别不喜欢这样)并导致很多误解。在您的逻辑中,fork 在您创建 Pool 时发生(第一个示例中的第 9 行,第二个示例中的第 8 行)。

在第一个示例中,子级继承了父级创建的同一 queue 对象。因此,他们成功地设法沟通,因为他们共享同一个频道。

相反,在第二个中,父母和孩子创建自己分开的queue 对象,这些对象完全独立。当孩子将元素放入queue 时,它会将其放入自己的元素中,而不会被任何人共享。

在第三个也是最后一个示例中,您创建了一个Process 对象,然后是一个Queue,然后您在该进程上调用start。猜猜fork 何时发生?当您调用 start 而不是创建 Process 对象时。这就是queue 成功共享的原因。这就是我说multiprocessing API 有点误导的意思。

【讨论】:

  • 感谢您的回答!但是当我尝试Process()实现多处理的时候,Process对象之后创建的Queue对象是被父共享的(我可以拿到放在子里面的元素)。那么你的逻辑适用于此吗?
  • 你能用Process链接逻辑吗?也许将其附加到上述问题。
  • 扩展了我的答案以涵盖最后一种情况。
猜你喜欢
  • 2021-03-20
  • 1970-01-01
  • 2016-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 2014-08-25
  • 2017-03-07
相关资源
最近更新 更多