Python信号处理器无法在程序退出前终止子进程的问题求助
Python信号处理器无法在程序退出前终止子进程的问题求助
我想通过信号处理器来平滑终止我的Python脚本,但遇到了一个头疼的问题——当用键盘中断(比如Ctrl+C)时,我写的信号处理器还没执行完,程序就直接退出了。有没有大佬能给点提示,怎么让处理器完整完成终止操作?
我的代码如下:
import sys,subprocess,signal def signal_handler(sig, frame): zipProc.terminate() zipProc.wait() sys.exit('Stopped') test_dir = '/mnt/Z/testdir' out_file = '/mnt/Z/testdir.7z' cmd = ['7z', 'a', '-t7z', out_file, test_dir] zipProc = subprocess.Popen(cmd) zipProc.communicate() for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT, signal.SIGHUP]: signal.signal(sig, signal_handler)
问题分析
你代码里的核心问题是信号处理器注册的时机太晚了!你调用zipProc.communicate()之后才去注册信号,而communicate()方法会一直阻塞,直到子进程(也就是7z压缩任务)完全结束。这就意味着,在压缩过程中,你的信号处理器根本还没被注册到系统里——此时按下Ctrl+C,系统只会用默认的信号处理逻辑直接终止程序,自然不会执行你写的signal_handler。
解决方案
把信号处理器的注册步骤提前到启动子进程之后、调用communicate()之前就好。这样在压缩任务运行的整个过程中,信号处理器都是生效的,一旦收到中断信号,就能顺利执行你的终止逻辑。修改后的代码如下:
import sys,subprocess,signal def signal_handler(sig, frame): zipProc.terminate() zipProc.wait() sys.exit('Stopped') test_dir = '/mnt/Z/testdir' out_file = '/mnt/Z/testdir.7z' cmd = ['7z', 'a', '-t7z', out_file, test_dir] zipProc = subprocess.Popen(cmd) # 先注册所有需要监听的信号 for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT, signal.SIGHUP]: signal.signal(sig, signal_handler) # 再等待子进程完成 zipProc.communicate()
另外补充个小细节:sys.exit()本质是抛出SystemExit异常,如果你的代码里有其他异常捕获逻辑,可能会影响它的执行。如果想要更稳妥地直接终止程序,可以考虑用os._exit()代替sys.exit(),不过大多数场景下sys.exit()已经足够用啦。
备注:内容来源于stack exchange,提问作者Bret Hess
相关产品推荐
相关产品推荐

