如何在Python中通過信號殺死父進程后確保子進程也終止?

如何在Python中通過信號殺死父進程后確保子進程也終止?

python信號處理:優(yōu)雅地終止父進程及其子進程

在Python多進程編程中,使用信號終止父進程后,子進程可能持續(xù)運行,這通常需要更精細的進程管理策略。本文探討此問題并提供解決方案。

問題描述

假設a.py創(chuàng)建了一個父進程和一個子進程,父進程ID寫入文件。b.py讀取此ID并發(fā)送終止信號(SIGTERM)。然而,父進程終止后,子進程可能繼續(xù)運行。

以下為示例代碼(與原文略有不同,更簡潔易懂,并修復了原代碼中的錯誤):

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} 發(fā)送 SIGTERM 信號") except FileNotFoundError:     print("pidfile.txt 未找到") except Exception as e:     print(f"發(fā)生錯誤: {e}") 

解決方案:利用進程組

解決此問題關鍵在于理解進程組的概念。父進程及其子進程屬于同一個進程組。通過向進程組發(fā)送信號,可以確保所有進程都接收到信號。

改進后的代碼:

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) # 向進程組發(fā)送信號         print(f"已向進程組 {pgid} 發(fā)送 SIGTERM 信號") except FileNotFoundError:     print("pidfile.txt 未找到") except Exception as e:     print(f"發(fā)生錯誤: {e}")

通過使用os.getpgid(0)獲取進程組ID,并將進程組ID寫入文件,b.py使用os.killpg()向整個進程組發(fā)送SIGTERM信號,確保父進程和子進程都被干凈地終止。 此外,a.py中的child.join()確保父進程等待子進程結束后才退出,避免了競態(tài)條件。 最后,代碼也進行了更健壯的異常處理。

這個改進后的方案更可靠,避免了原代碼中可能存在的潛在問題,并提供了更清晰的代碼結構。

? 版權聲明
THE END
喜歡就支持一下吧
點贊8 分享