[英]Python multiprocessing - watchdog process?
在典型的“發布/訂閱”設置中,我有一組長時間運行的過程,帶有通信隊列。
我想做兩件事,但我想不出如何同時完成兩項工作:
我可以單獨進行(2):
try:
while True:
for process in workers + consumers:
if not process.is_alive():
logger.critical("%-8s%s died!", process.pid, process.name)
sleep(3)
except KeyboardInterrupt:
# Python propagates CTRL+C to all workers, no need to terminate them
logger.warn('Received CTR+C, shutting down')
上面的代碼塊阻止了我執行(1)。
因此,我決定將代碼移入自己的過程。
這是行不通的,因為process.is_alive()
僅適用於檢查其子級狀態的父級。 在這種情況下,我要檢查的進程將是同級而不是子進程。
我對如何進行感到有些困惑。 我的主流程如何在支持子流程的同時監視子流程?
實際上, multiprocessing.Pool
實際上已經內置了一個看門狗。 它運行一個線程,該線程每隔0.1秒檢查一次,看是否有工人死亡。 如果有,它將啟動一個新的位置來代替它:
def _handle_workers(pool):
thread = threading.current_thread()
# Keep maintaining workers until the cache gets drained, unless the pool
# is terminated.
while thread._state == RUN or (pool._cache and thread._state != TERMINATE):
pool._maintain_pool()
time.sleep(0.1)
# send sentinel to stop workers
pool._taskqueue.put(None)
debug('worker handler exiting')
def _maintain_pool(self):
"""Clean up any exited workers and start replacements for them.
"""
if self._join_exited_workers():
self._repopulate_pool()
這主要用於實現maxtasksperchild
關鍵字參數,在某些情況下實際上存在問題。 如果某個進程在運行map
或apply
命令時死亡,並且該進程正在處理與該調用相關的任務,則它將永遠不會完成。 有關該行為的更多信息,請參見此問題 。
就是說,如果您只想知道某個進程已死,則可以創建一個線程(而不是進程)來監視池中所有進程的pid,並且如果列表中的pid曾經更改,您就知道進程崩潰:
def monitor_pids(pool):
pids = [p.pid for p in pool._pool]
while True:
new_pids = [p.pid for p in pool._pool]
if new_pids != pids:
print("A worker died")
pids = new_pids
time.sleep(3)
編輯:
如果要滾動自己的Pool
實現,則可以從multiprocessing.Pool
獲取提示,並在父進程的后台線程中運行監視代碼。 檢查進程是否仍在運行的速度很快,因此,采用GIL的后台線程所浪費的時間可以忽略不計。 考慮一下multiprocessing.Process
看門狗每0.1秒運行一次! 每3秒鍾運行一次不會造成任何問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.