multiprocessing不使用Pool生成进程且避免僵尸进程的问题排查
问题根因
你遇到的问题是两处逻辑编写错误导致的统计异常,以及一处不规范的传参写法:
- 第一处错误:在循环替换进程时,你join的是旧进程
p,但往joined_list里追加的却是刚创建的新进程list_process[i]的pid,所以最早启动的4个进程的pid永远不会出现在记录列表里,你误以为这些进程没有被join,实际上join操作本身是执行了的,只是记录错了pid。 - 第二处错误:最后收尾遍历
list_process做join的循环里,你直接用了之前外层for i in range(processes)循环结束后残留的i值(固定为3),所以每次往列表追加的都是list_process[3]的pid,才会出现大量重复的6216记录。 - 额外不规范写法:创建Process时的
args参数要求传入元组,你写的args=(targets.pop(0))会被识别为普通表达式而非元组,正确写法应该加末尾逗号:args=(targets.pop(0),),避免后续参数传递异常。
修正后的代码
from multiprocessing import Process import time def target(task): print(f"Working for {task*2} seconds ...") time.sleep(task*2) if __name__ == '__main__': started_count = 0 joined_count = 0 joined_list = [] processes = 4 list_process = [None] * processes targets = [[2] for i in range(10)] while targets: for i in range(processes): p = list_process[i] if not (p and p.is_alive()): new_p = Process(target=target, args=(targets.pop(0),)) new_p.start() print(new_p.pid) started_count += 1 list_process[i] = new_p if p: assert(not p.is_alive()) p.join() # 追加旧进程的pid joined_list.append(p.pid) joined_count += 1 for process in list_process: if process: process.join() # 追加当前遍历到的进程的pid joined_list.append(process.pid) joined_count += 1 print(f'Final started count: {started_count}, final joined count: {joined_count}') print(joined_list)
修正后joined_list会正确记录所有被join的进程pid,不存在漏join的情况,也不会产生僵尸进程。
内容的提问来源于stack exchange,提问作者IndiaSke
相关产品推荐
相关产品推荐

