Python多进程代码执行顺序不符合预期问题排查求助
问题原因分析
你的代码在Windows系统下运行时,会触发子进程重新导入整个脚本的机制,这是Windows多进程的特性(Unix/Linux采用fork机制,不会重复执行整个脚本)。具体执行流程如下:
- 主进程启动后,执行
main_f(),打印01,进入if __name__ == '__main__':块,打印02并启动子进程。 - 子进程启动时会重新加载整个脚本,此时子进程的
__name__值不是__main__,所以:- 子进程会执行
main_f(),打印01,但不会进入if块内的代码逻辑。 - 子进程继续执行脚本末尾的
print('05'),打印05。
- 子进程会执行
- 之后子进程才会执行目标函数
f1,打印03并将hello world放入队列。 - 主进程在
q.get()处等待,拿到队列数据后打印hello world,接着执行mp.join()等待子进程结束,打印04,最后主进程执行末尾的print('05')。
这就是你看到02之后出现01、05的核心原因——子进程重复执行了脚本中的main_f()和末尾的print('05')。
修复方案
要让代码按预期顺序执行,必须把顶层可执行代码(比如main_f()的调用、print('05'))全部放入if __name__ == '__main__':块中,避免子进程重复执行这些逻辑。修改后的代码如下:
from multiprocessing import Process, Queue # 大计算/复杂任务用多进程,否则用普通函数 q = Queue() # 父子进程间通信的队列 def f1(x, q): print('03') x = x + " world" q.put(x) def main_f(): print('01') mp = Process(target=f1, args=("hello", q,)) print('02') mp.start() print(q.get()) mp.join() print('04') if __name__ == '__main__': # 仅主进程执行此块,避免子进程重复执行代码 main_f() print('05')
修复后执行顺序说明
- 主进程进入
if __name__ == '__main__':块,调用main_f()。 main_f()中打印01,创建进程对象,打印02并启动子进程。- 子进程执行
f1,打印03,将hello world放入队列。 - 主进程通过
q.get()获取队列数据,打印hello world,等待子进程结束(mp.join())后打印04。 main_f()执行完毕,主进程打印05。
最终输出顺序会完全符合你的预期:01,02,03,hello world,04,05。
内容的提问来源于stack exchange,提问作者user13964720
相关产品推荐
相关产品推荐

