Python 3.x 为什么多进程在同一进程中运行?

Python 3.x 为什么多进程在同一进程中运行?,python-3.x,concurrency,multiprocessing,windows-7-x64,Python 3.x,Concurrency,Multiprocessing,Windows 7 X64,我从运行以下解决方案: 它应该输出如下内容: I am number 0 in process 19139 I am number 1 in process 19138 I am number 2 in process 19140 I am number 3 in process 19139 I am number 4 in process 19140 [19139, 19138, 19140, 19139, 19140] 但我只得到了 [4212, 4212, 4212, 4212, 421

我从运行以下解决方案:

它应该输出如下内容:

I am number 0 in process 19139
I am number 1 in process 19138
I am number 2 in process 19140
I am number 3 in process 19139
I am number 4 in process 19140
[19139, 19138, 19140, 19139, 19140]
但我只得到了

[4212, 4212, 4212, 4212, 4212]
如果我使用10个以上的进程来feed pool.map 1000000的范围,我最多会看到两个不同的PID


为什么我的
多处理
副本似乎在同一个进程中运行所有内容?

TL;DR:任务不是以任何方式专门分配的,也许您的任务太短了,它们在其他流程开始之前就全部完成了

多处理
的来源来看,任务似乎只是放在一个
队列
,工作进程从该队列中读取(函数
工作进程
池中读取。_inqueue
)。没有经过计算的分配,工人们只是争先恐后地尽可能努力工作

因此,最有可能的赌注是,由于任务非常短,因此一个进程在其他进程有机会查看甚至开始之前完成了所有任务。您可以通过在任务中添加两秒钟的
睡眠
来轻松检查是否存在这种情况

我会注意到,在我的机器上,所有任务都分布在进程上,非常均匀(也适用于#进程>内核)。因此,似乎存在一些系统依赖性,即使所有进程在工作排队之前都应该设置
.start()


下面是来自
worker
的一些经过裁剪的源代码,它显示每个进程都只是从队列中读取任务,因此以伪随机顺序:

def worker(inqueue, outqueue, ...):
    ...
    get = inqueue.get
    ...
    while maxtasks is None or (maxtasks and completed < maxtasks):
        try:
            task = get()
        ...

编辑:关于进程启动太慢的部分可能是错误的,因此我删除了它。所有进程在任何工作排队(可能依赖于)之前都被
.start()
调用。我找不到进程现在是否已准备就绪。
.start()
返回。

您从哪个示例中获取此信息?这可能是真的,要执行的代码太快了,强迫它在多个线程之间分割工作没有任何好处。在我的机器上,我相当一致地得到了您示例中的所有pid,以及10个进程上的100个任务。因此,这似乎有点依赖于上下文。请注意,它还有一个
chunksize
参数,可用于固定发送到子进程的块的大小。因此,您可以通过将
chunksize
设置为较小的值来稍微改变行为。在任何情况下:
Pool
都是一种简单的任务分配方式,您不需要关心具体由谁执行任务等。它的默认设置在几乎所有情况下都能正常工作,所以在您发现性能的真正问题之前,不要担心这一点…@Makoto,问题中链接了该示例。这实际上是Mark在Windows上的例子,使用多个进程效率相当低。Python可能考虑到了这一点。结果表明,我的机器需要大约
时间的延迟。睡眠(0.0005)
来获得不同的进程。我猜
进程
返回和系统上可用的进程之间有0.0005s的延迟,但是我在网上找不到文档,也无法在我的系统上测试,因为没有明显的延迟。。。
def worker(inqueue, outqueue, ...):
    ...
    get = inqueue.get
    ...
    while maxtasks is None or (maxtasks and completed < maxtasks):
        try:
            task = get()
        ...
self._reader, self._writer = Pipe(duplex=False)