如何在Python中通过信号杀死父进程后确保子进程也终止?

如何在Python中通过信号杀死父进程后确保子进程也终止?

python信号处理:优雅地终止父进程及其子进程

在Python多进程编程中,使用信号终止父进程后,子进程可能持续运行,这通常需要更精细的进程管理策略。本文探讨此问题并提供解决方案。

问题描述

假设a.py创建了一个父进程和一个子进程,父进程ID写入文件。b.py读取此ID并发送终止信号(SIGTERM)。然而,父进程终止后,子进程可能继续运行。

以下为示例代码(与原文略有不同,更简洁易懂,并修复了原代码中的错误):

a.py:

立即学习Python免费学习笔记(深入)”;

import multiprocessing import os import signal import time  def child_process():     while True:         print("子进程运行中...")         time.sleep(1)  if __name__ == "__main__":     child = multiprocessing.Process(target=child_process)     child.start()     with open("pidfile.txt", "w") as f:         f.write(str(os.getpid()))     child.join()  # 等待子进程结束     print("父进程结束") 

b.py:

import os import signal  try:     with open("pidfile.txt", "r") as f:         pid = int(f.read())         os.kill(pid, signal.SIGTERM)         print(f"已向进程 {pid} 发送 SIGTERM 信号") except FileNotFoundError:     print("pidfile.txt 未找到") except Exception as e:     print(f"发生错误: {e}") 

解决方案:利用进程组

解决此问题关键在于理解进程组的概念。父进程及其子进程属于同一个进程组。通过向进程组发送信号,可以确保所有进程都接收到信号。

改进后的代码:

a.py:

立即学习Python免费学习笔记(深入)”;

import multiprocessing import os import signal import time  def child_process():     while True:         print("子进程运行中...")         time.sleep(1)  if __name__ == "__main__":     child = multiprocessing.Process(target=child_process)     child.start()     pgid = os.getpgid(0) # 获取当前进程组ID     with open("pidfile.txt", "w") as f:         f.write(str(pgid))     child.join()     print("父进程结束")

b.py:

import os import signal  try:     with open("pidfile.txt", "r") as f:         pgid = int(f.read())         os.killpg(pgid, signal.SIGTERM) # 向进程组发送信号         print(f"已向进程组 {pgid} 发送 SIGTERM 信号") except FileNotFoundError:     print("pidfile.txt 未找到") except Exception as e:     print(f"发生错误: {e}")

通过使用os.getpgid(0)获取进程组ID,并将进程组ID写入文件,b.py使用os.killpg()向整个进程组发送SIGTERM信号,确保父进程和子进程都被干净地终止。 此外,a.py中的child.join()确保父进程等待子进程结束后才退出,避免了竞态条件。 最后,代码也进行了更健壮的异常处理。

这个改进后的方案更可靠,避免了原代码中可能存在的潜在问题,并提供了更清晰的代码结构。

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享