如何避免按下Ctrl+C时终止subprocess.Popen启动的子进程
解决Ctrl+C导致subprocess子进程退出的问题
当你在Python控制台按下Ctrl+C时,父进程和子进程默认属于同一个进程组,系统会把SIGINT信号发送给整个进程组里的所有进程,所以子进程也会收到信号并退出。要避免这种情况,核心是让子进程脱离父进程的进程组,或者阻止信号传递到子进程,下面是几种可行的方法:
方法1:使用start_new_session=True参数(跨平台推荐)
这个参数会让子进程启动一个新的会话,脱离原来的进程组,这样父进程收到的SIGINT信号不会传递给子进程:
import subprocess p = subprocess.Popen(["python3", script_file], start_new_session=True)
方法2:使用preexec_fn设置进程组(Unix/Linux/macOS适用)
通过preexec_fn调用os.setpgrp(),让子进程成为新进程组的组长,同样能隔离信号:
import subprocess import os p = subprocess.Popen(["python3", script_file], preexec_fn=os.setpgrp)
方法3:Windows平台专属处理
Windows没有进程组的概念,Ctrl+C信号会发送给控制台关联的所有进程,这时可以用CREATE_NEW_PROCESS_GROUP标志:
import subprocess import sys if sys.platform == 'win32': # Windows下使用创建新进程组的标志 p = subprocess.Popen(["python", script_file], creationflags=subprocess.CREATE_NEW_PROCESS_GROUP) else: # Unix系使用start_new_session p = subprocess.Popen(["python3", script_file], start_new_session=True)
需要注意的是,如果你之后需要手动终止子进程,得自己调用p.terminate()或p.kill()发送信号,因为子进程已经脱离了父进程的进程组,不会再跟着父进程一起退出。
内容的提问来源于stack exchange,提问作者bumpbump
相关产品推荐
相关产品推荐

