Python,多处理:process.join() 做什么?
Python, Multiprocessing: what does process.join() do?
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
我试过运行这段代码,这是我得到的输出
99999999
99999999
2.73401999474
99999999
99999999
99999999
有时
99999999
99999999
3.72434902191
99999999
99999999
99999999
99999999
99999999
在这种情况下,循环函数被调用了 7 次而不是 5 次。为什么会出现这种奇怪的行为?
我也对p.join()
语句的作用感到困惑。它是结束任何一个进程还是同时结束所有进程?
你做事的方式有一些问题,试试这个:
start = time.time()
procs = []
for i in xrange(5):
p = Process(target=loop, args=(limit,))
p.start()
procs.append(p)
[p.join() for p in procs]
问题是您没有跟踪单个进程(循环内的 p 变量)。你需要把它们放在身边,这样你才能与它们互动。此更新会将它们保留在数组中,然后在最后加入所有这些。
输出如下所示:
99999999
99999999
99999999
99999999
99999999
6.29328012466
请注意,现在 运行 所花费的时间也会在执行结束时打印出来。
此外,我 运行 你的代码无法让循环执行多次。
join 函数当前将等待您调用的最后一个进程完成,然后再转到下一部分代码。如果您了解了您所做的一切,您应该明白为什么会得到“奇怪”的输出。
for i in xrange(5):
p = Process(target=loop, args=(limit,))
p.start()
这将依次启动 5 个新进程。这些都是同时运行。 至少,由调度程序决定当前正在处理的进程。
这意味着您现在有 5 个进程 运行:
Process 1
Process 2
Process 3
Process 4
Process 5
p.join()
这将等待 p
进程完成 进程 5 因为这是分配给 p
的最后一个进程。
现在假设 进程 2 首先完成,然后是 进程 5,这是完全可行的,因为调度程序可以为这些进程提供更多CPU.
上的时间
Process 1
Process 2 prints 99999999
Process 3
Process 4
Process 5 prints 99999999
p.join()
行现在将移至下一部分,因为 p
进程 5 已完成。
end = time.time()
print end - start
这部分打印它的部分,现在有 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()
这将等待第一个进程,然后是第二个进程,依此类推。一个进程是否先于另一个进程完成并不重要,因为在脚本继续之前必须等待列表中的每个进程。
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
我试过运行这段代码,这是我得到的输出
99999999
99999999
2.73401999474
99999999
99999999
99999999
有时
99999999
99999999
3.72434902191
99999999
99999999
99999999
99999999
99999999
在这种情况下,循环函数被调用了 7 次而不是 5 次。为什么会出现这种奇怪的行为?
我也对p.join()
语句的作用感到困惑。它是结束任何一个进程还是同时结束所有进程?
你做事的方式有一些问题,试试这个:
start = time.time()
procs = []
for i in xrange(5):
p = Process(target=loop, args=(limit,))
p.start()
procs.append(p)
[p.join() for p in procs]
问题是您没有跟踪单个进程(循环内的 p 变量)。你需要把它们放在身边,这样你才能与它们互动。此更新会将它们保留在数组中,然后在最后加入所有这些。
输出如下所示:
99999999
99999999
99999999
99999999
99999999
6.29328012466
请注意,现在 运行 所花费的时间也会在执行结束时打印出来。
此外,我 运行 你的代码无法让循环执行多次。
join 函数当前将等待您调用的最后一个进程完成,然后再转到下一部分代码。如果您了解了您所做的一切,您应该明白为什么会得到“奇怪”的输出。
for i in xrange(5):
p = Process(target=loop, args=(limit,))
p.start()
这将依次启动 5 个新进程。这些都是同时运行。 至少,由调度程序决定当前正在处理的进程。
这意味着您现在有 5 个进程 运行:
Process 1
Process 2
Process 3
Process 4
Process 5
p.join()
这将等待 p
进程完成 进程 5 因为这是分配给 p
的最后一个进程。
现在假设 进程 2 首先完成,然后是 进程 5,这是完全可行的,因为调度程序可以为这些进程提供更多CPU.
上的时间Process 1
Process 2 prints 99999999
Process 3
Process 4
Process 5 prints 99999999
p.join()
行现在将移至下一部分,因为 p
进程 5 已完成。
end = time.time()
print end - start
这部分打印它的部分,现在有 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()
这将等待第一个进程,然后是第二个进程,依此类推。一个进程是否先于另一个进程完成并不重要,因为在脚本继续之前必须等待列表中的每个进程。