Python,多处理:process.join() 做什么?

Sou*_*nak 3 python parallel-processing multiprocessing python-multiprocessing

import time
from multiprocessing import Process

def loop(limit):
    for i in xrange(limit):
        pass
    print i

limit = 100000000 #100 million

start = time.time()    

for i in xrange(5):
    p = Process(target=loop, args=(limit,))
    p.start()
p.join()

end = time.time()
print end - start
Run Code Online (Sandbox Code Playgroud)

我尝试运行此代码,这是我得到的输出

99999999
99999999
2.73401999474
99999999
99999999
99999999
Run Code Online (Sandbox Code Playgroud)

而有时

99999999
99999999
3.72434902191
99999999
99999999
99999999
99999999
99999999
Run Code Online (Sandbox Code Playgroud)

在这种情况下,循环函数被调用了 7 次而不是 5 次。为什么会有这种奇怪的行为?

我也对p.join()声明的作用感到困惑。它是同时结束任何一个进程还是所有进程?

Son*_*ngy 5

join 函数当前将等待您调用的最后一个进程完成,然后再进入下一段代码。如果你完成你所做的,你应该明白为什么你会得到“奇怪的”输出。

for i in xrange(5):
    p = Process(target=loop, args=(limit,))
    p.start()
Run Code Online (Sandbox Code Playgroud)

这将一个接一个地启动 5 个新进程。这些都是同时运行的。至少,由调度程序决定当前正在处理哪个进程。

这意味着您现在有 5 个进程正在运行:

过程1

过程2

过程3

过程4

过程5

p.join()
Run Code Online (Sandbox Code Playgroud)

这将等待p进程完成进程 5,因为这是分配给的最后一个进程p

现在让我们说进程 2首先完成,然后是进程 5,这是完全可行的,因为调度程序可以在 CPU 上为这些进程提供更多时间。

过程1

处理 2 打印 99999999

过程3

过程4

处理 5 次 打印 99999999

p.join()作为行会现在进入下一部分p 过程5结束。

end = time.time()
print end - start
Run Code Online (Sandbox Code Playgroud)

此部分打印其部分,现在在此输出后仍有 3 个进程仍在进行。

其他进程完成并在那里打印 99999999。

要修复此行为,您将需要.join()所有进程。为此,您可以将代码更改为此...

processes = []

for i in xrange(5):
    p = Process(target=loop, args=(limit,))
    p.start()
    processes.append(p)

for process in processes:
    process.join()
Run Code Online (Sandbox Code Playgroud)

这将等待第一个进程,然后是第二个进程,依此类推。如果一个进程在另一个之前完成并不重要,因为在脚本继续之前必须等待列表中的每个进程。