gpt4 book ai didi

python - 多进程模块中子进程的运行顺序

转载 作者:太空狗 更新时间:2023-10-29 20:22:24 27 4
gpt4 key购买 nike

用for循环启动多进程。

import os
from multiprocessing import Process

def run_proc(name):
print('child process %s (%s) running ...' %(name,os.getpid()))

if __name__ == '__main__':
print('parent process %s.' %os.getppid())
for i in range(5):
p = Process(target=run_proc,args=(str(i),))
print('process will start'+str(i))
p.start()
p.join()
print('process is end')

我得到了结果。

parent process 6497.  
process will start
process will start
child process 0 (6984) running ...
process will start
process will start
process will start
child process 2 (6986) running ...
child process 1 (6985) running ...
child process 3 (6987) running ...
child process 4 (6988) running ...
process is end

为什么早创建的子流程后执行?
为什么得不到下面的结果?

parent process 6497.  
process will start
process will start
child process 0 (6984) running ...
process will start
process will start
process will start
child process 1 (6986) running ...
child process 2 (6985) running ...
child process 3 (6987) running ...
child process 4 (6988) running ...
process is end

Jean-François Fabre 所说的是关于如何创建以下结果:

parent process 6497.
process will start
child process 0 (9639) running ...
process will start
child process 1 (9640) running ...
process will start
child process 2 (9641) running ...
process will start
child process 3 (9643) running ...
process will start
child process 4 (9644) running ...
process is end

我可以得到它只是改变 p.join 在 for 循环中,如下所示:

import os
from multiprocessing import Process

def run_proc(name):
print('child process %s (%s) running ...' %(name,os.getpid()))

if __name__ == '__main__':
print('parent process %s.' %os.getppid())
for i in range(5):
p = Process(target=run_proc,args=(str(i),))
print('process will start'+str(i))
p.start()
p.join()
print('process is end')

我想知道为什么我的代码会产生以下输出

parent process 6497.  
process will start
process will start
child process 0 (6984) running ...
process will start
process will start
process will start
child process 2 (6986) running ...
child process 1 (6985) running ...
child process 3 (6987) running ...
child process 4 (6988) running ...
process is end

代替:

parent process 6497.  
process will start
process will start
child process 0 (6984) running ...
process will start
process will start
process will start
child process 1 (6986) running ...
child process 2 (6985) running ...
child process 3 (6987) running ...
child process 4 (6988) running ...
process is end

这是一个不同的问题。

最佳答案

这里有一个 race condition在创建流程的主流程与尝试启动的流程(以及子流程本身)之间。

只要您从主进程发出 p.start() 命令,子进程就可以运行(并打印)。但是主进程也在努力创建下一个子进程。谁将首先打印下一行?很难知道。如果主进程成功创建了下一个子进程,那么现在两个子进程之间存在竞争条件:您正在经历什么。

进程可以并行运行,但它们在调用操作系统时仍然有同步点。谁先到达操作系统,谁就先得到服务(例如:打印到控制台)。

当然,将p.join() 放在循环中可以恢复顺序,同时也取消了多处理的效果,因为主进程等待直到子进程在创建另一个之前结束

这通常无关紧要,因为您正在执行一些并行任务。

我会首先在列表推导式中创建进程,然后循环启动它们,并稍作延迟以确保进程在创建下一个进程之前启动并打印。

process_list = [Process(target=run_proc,args=(str(i),)) for i in range(5)]
for i,p in enumerate(process_list):
print('process {} will start'.format(i))
p.start()
time.sleep(0.1)

当主进程稍等片刻时,这会为子进程提供喘息空间以启动和打印。

另请注意,您的最后一个 p.join() 只是加入循环的最后一个进程,它应该是(现在使用我们全新的 process_list):

for p in process_list:
p.join()

在大多数情况下,按顺序开始/结束并不重要。您可以预先计算主流程中的所有排序信息(就像您通过为流程名称分配递增的数字所做的那样)。

请注意,经典问题可能不是确保进程按顺序启动,而是它们产生的结果可以与您提供的输入相匹配(向进程传递输入列表,它们产生输出列表,所以最后你知道哪个输入提供了哪个输出)。

在这种情况下,寻找 multiprocessing.poolmap 函数 ( Python multiprocessing.pool sequential run of processes )

关于python - 多进程模块中子进程的运行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48208387/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com