Python多进程调用terminate时无法正确触发预设信号处理函数问题
问题1:信号处理函数打印逻辑错误
你定义的handle_exit信号回调函数的第一个参数就是触发回调的信号编号,你代码中没有读取该参数,反而直接打印了全局导入的signal模块对象,所以输出里才会出现signal模块的安装路径。
问题2:信号处理函数无主动退出逻辑,进程终止后继续运行
Unix系统下,信号处理函数执行完成后,默认会回到被信号中断的代码位置继续执行,你没有在handle_exit里加退出进程的逻辑,所以处理完信号后,函数会回到原来的time.sleep(2)逻辑继续运行,才会不断输出后续的hello。
问题3:超时判断逻辑存在偏差
你设置max_time=4,但判断条件是i > max_time才触发终止,i从0开始每次加1、每次等待1秒,实际会等待5秒才触发终止,和你预期的4秒超时不符。另外递归检测超时没有必要,用process.join(timeout)原生方法即可实现相同逻辑,还能避免长超时场景下的递归栈溢出问题。
修正后的完整示例代码
import multiprocessing import signal import time import sys def exporter_methods(return_dict): def handle_exit(signal_num, frame): return_dict["error"] = True print("Program were aborted by signal:", signal_num) # 执行完清理后主动退出进程 sys.exit(1) print("signal registration") signal.signal(signal.SIGTERM, handle_exit) signal.signal(signal.SIGINT, handle_exit) for i in range(30): time.sleep(2) print("hello") if __name__ == '__main__': manager = multiprocessing.Manager() return_dict = manager.dict() proc = multiprocessing.Process(target=exporter_methods, args=(return_dict, )) print("Start process") proc.start() # 原生超时等待,无需递归 proc.join(timeout=4) if proc.is_alive(): print(f'Terminating child {proc.pid}') proc.terminate() proc.join() print(f'Child {proc.pid} ended with {proc.exitcode}')
内容的提问来源于stack exchange,提问作者Александр Гордеев
相关产品推荐
相关产品推荐

