Python 3.10多进程循环内function2莫名停止运行求助
Python多进程并行处理卡住问题分析
问题现象
在Python 3.10环境下执行多进程并行处理时,程序初期运行正常,但运行至某一阶段后,for循环内的function2不再执行,无任何报错信息。排查发现function1仍在接收新数据,但其返回结果无法传递至function2。
相关代码
import multiprocessing as mp import logging import signal import sys, os from rich.progress import Progress def initializer(): signal.signal(signal.SIGINT, signal.SIG_IGN) def CPU_Parallelization(Nb_CoresToBeUsed, output_queue, input_data, output_result): mp.util.log_to_stderr(mp.util.DEBUG) p = mp.Pool(processes=Nb_CoresToBeUsed, initializer=initializer) with Progress() as progress: try: # Bar Progress Increment task_id = progress.add_task("[cyan]Working...", total=len(input_data)) with p as pool: for Out_1,\ Out_2,\ Out_3,\ Out_4 in pool.imap(function1, input_data): final_output = function2(out_1, Out2, Out3, Out4) progress.advance(task_id) p.close() p.join() except Exception as e: # <--- exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] print(exc_type, fname, exc_tb.tb_lineno) print(e) p.close() p.join() def funct1(input_data): try: Out1 = 1 Out2 = 2 Out3 = 3 Out4 = 4 except Exception as e: print(e) return Out1, Out2, Out3, Out4
问题原因分析
1. 函数名拼写错误,导致子进程异常退出
代码中定义的处理函数是funct1,但在pool.imap中调用的是function1,子进程启动时会触发NameError异常。由于imap是惰性迭代,主进程会一直等待子进程返回结果,但子进程已经崩溃,无法传递结果,导致主进程的for循环卡住,function2自然无法继续执行。
2. 变量名大小写不匹配,触发静默报错
在for循环中,接收的变量是Out_1、Out_2、Out_3、Out_4,但调用function2时传入的是out_1、Out2、Out3、Out4——变量名大小写和下划线完全不匹配,会触发NameError。但因为imap的迭代特性,这个错误会在迭代到对应元素时才抛出,若主进程此时已经因为子进程的异常卡住,这个错误甚至不会被捕获到。
3. Pool对象的重复生命周期管理
代码中先创建了p = mp.Pool(...),随后又用with p as pool:,with语句会自动调用Pool的close()和join()方法,后续手动调用的p.close()和p.join()属于重复操作,可能导致进程池资源释放异常,加剧卡住的情况。
4. 异常捕获的局限性
子进程中的异常(比如函数名拼写错误)无法直接传递到主进程的try-except块中,主进程只能等待子进程返回结果,而无法感知子进程已经崩溃,因此没有任何报错输出,导致问题难以排查。
内容的提问来源于stack exchange,提问作者EdouardDKP
相关产品推荐
相关产品推荐

