簡體   English   中英

終止 python 子進程的安全方法?

[英]Safe way to terminate a python subprocess?

我正在使用 python 的multiprocessing模塊同時處理多個函數。 每個衍生進程的 function 都會獲得一些初始輸入 arguments 和Pipe連接以將其結果發回。 由於各種原因,我必須使用像這樣的單個進程,即像Pool.map_async()這樣的工具 - 方法不在桌面上。

有時,我需要終止一個需要很長時間才能完成的進程。

根據流程文檔

警告:如果在關聯進程使用 pipe 或隊列時使用此方法,則 pipe 或隊列可能會損壞並且可能無法被其他進程使用。 類似地,如果進程獲得了鎖或信號量等,那么終止它很可能導致其他進程死鎖。

我不擔心第一部分,因為每個進程都有自己的 pipe object,但是我如何確定一個進程是否“獲得了鎖或信號量” ,和/或以對我的其余部分安全的方式終止程序?

“終止python 子進程安全方法?”

好吧,如果有的話,你永遠不會遇到這個。

如果您的實際需求可以證明這樣做的成本是合理的,那么最好的解決方法是向可靠處理、設計強大、彈性、自我修復系統的大師學習——比如在 NASA 運營的 Margaret HAMILTON 女士(麻省理工學院)阿波羅登月計划,將 AGC(阿波羅制導計算機)設計得如此正確和如此出色,它可以在自身的死鎖風險中幸存下來,防止鷹着陸器墜毀月球表面。

最好的靈感來自,如果使用強大且獨立的多節點到多節點通信平面框架 ZeroMQ 或 nanomsg 設計安全和自我修復的自治組件,pythonistas 可以使用它。

附帶說明:檢查為什么您的子流程“完成時間太長”可能是值得的。

至於警告,它與您何時“鎖定”資源以供使用有關。 例如:

# function to withdraw from account 
def withdraw(balance, lock):     
    for _ in range(10000): 
        lock.acquire() 
        balance.value = balance.value - 1
        lock.release() 

來源: https://www.geeksforgeeks.org/synchronization-pooling-processes-python/

如果您在子進程執行lock.acquire() lock.release()終止子進程,您將遇到死鎖情況。

所以問題是,您是否在要終止的進程中使用任何 threading.Lock 或 threading.Semaphore 對象?

我希望這有助於理解終止子進程/線程是否安全。

編輯:順便說一句,您還應該考慮使用 kill() 而不是 terminate()。

在 *nix 上,您可以嘗試將 SIGINT 發送到進程而不是終止/殺死它並捕獲 KeyboardInterrupt 異常以進行清理:

from multiprocessing import Process
import os
import time
import signal

def f():
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print('Do the emergency cleanup here')

p = Process(target=f)
p.start()
os.kill(p.pid, signal.SIGINT)
p.join()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM