如果我通过 终止 Python 进程Ctrl-C,则所有子进程(由 启动subprocess)都会死亡。但是,如果我通过 终止 Python 进程kill -2,子进程将继续运行。我认为这与发送(即)Ctrl-C相同。为什么行为不同?SIGINTkill -2
python进程及其由多进程或子进程启动的子进程都连接到同一个终端——具体来说,它们都是同一个进程组的一部分。当终端接收到 Ctrl-C 时,它将向连接到终端的所有进程发送 SIGINT,这就是为什么您会看到主 python 线程及其子线程接收到该信号。
当您这样做时,kill -2 PID您正在将 SIGINT 发送到该进程组的特定进程;其他进程将不会被选择。
相反,如果您这样做kill -2 -PGID(请注意减号和 )G,您将复制 Ctrl-C 的操作。这指示kill 将信号定位在进程组级别;组内的所有进程都会收到该信号。
您可以运行此命令来查看每个 python 进程的进程组 ID:
ps -o pgid,ppid,pid,lwp,sgi_p,fname,cmd -C python
Run Code Online (Sandbox Code Playgroud)
...示例输出....
PGID PPID PID LWP P COMMAND CMD
22706 19662 22706 22706 * python python parent.py
22706 22706 22707 22707 * python python /var/tmp/child.py
22706 22706 22708 22708 * python python /var/tmp/child.py
22706 22706 22709 22709 * python python /var/tmp/child.py
22706 22706 22710 22710 * python python /var/tmp/child.py
22706 22706 22711 22711 * python python /var/tmp/child.py
Run Code Online (Sandbox Code Playgroud)
(PGID:组ID,PPID:父ID,PID:进程ID,LWP:线程ID)
...然后将 SIGINT 发送到整个组:
kill -2 -22706
Run Code Online (Sandbox Code Playgroud)
有关 Ctrl-C 和进程组的详细解释,请参阅此处:https://unix.stackexchange.com/questions/149741/why-is-sigint-not-propagated-to-child-process-when-sent-to-its -父进程