Python多進程Pipe報錯“管道已關閉”如何解決?

Python多進程Pipe報錯“管道已關閉”如何解決?

python多進程Pipe中“管道已關閉”錯誤的解決方案

在使用Python的multiprocessing模塊中的Pipe方法進行進程間通信時,可能會遇到令人頭疼的“管道已關閉”錯誤。本文將深入分析該錯誤的成因,并提供可靠的解決方案。

問題根源在于主進程與子進程間的協調性。當子進程使用child_conn.recv()等待主進程發送數據時,如果主進程在子進程接收數據前意外終止,child_conn將被關閉,導致子進程嘗試讀取已關閉的管道,從而引發錯誤。

在原代碼中,子進程無限期地等待主進程信號,這在主進程提前結束時會引發問題。 有效的解決方法是:在子進程中使用try…except塊捕獲EOFError異常。當主進程退出時,child_conn會關閉,嘗試讀取數據將拋出EOFError。 通過捕獲此異常,可以防止程序崩潰,并允許子進程以更優雅的方式處理這種情況。

立即學習Python免費學習筆記(深入)”;

以下是改進后的service.py代碼:

import os from multiprocessing import Process, Pipe   def start_child_process(child_conn):     # 模擬長時間運行的任務     # run_server_for_long_time()     child_conn.send({"port": 123, "ret": 1, "pid": os.getpid()})      try:         signal = child_conn.recv()         if signal:             child_conn.close()     except EOFError as err:         print(f"Caught EOFError: {err}")   class Server:     def __init__(self):         self.child_conn = None         self.child = None         self.parent_conn, self.child_conn = Pipe()      def run(self):         self.child = Process(target=start_child_process, name="my_child_process", args=(self.child_conn,))         self.child.start()          data = self.parent_conn.recv()         result = {             "endpoints": {                 "http": f"http://127.0.0.1:{data['port']}/cmd",                 "ws": f"ws://127.0.0.1:{data['port']}/api",             }         }         return result      def stop(self):         self.parent_conn.send(True)         self.child.join()         self.child = None   if __name__ == "__main__":     server = Server()     r = server.run()     print("r:", r)

single.py代碼保持不變,仍然可以正常運行:

from service import Server import time   def main():     server = Server()     result = server.run()     print("r:", result)     time.sleep(5)     # server.stop()  # 解注釋后,問題依然解決   if __name__ == "__main__":     main()

通過捕獲EOFError異常,即使主進程提前結束,子進程也能干凈地退出,有效避免了“管道已關閉”錯誤,提升了程序的健壯性。

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