python清理子進程機制剖析
起步
在我的印象中,python的機制會自動清理已經(jīng)完成任務的子進程的。通過網(wǎng)友的提問,還真看到了僵尸進程。
import multiprocessing as mp import os import time def pro(): print ("os.pid is ", os.getpid()) if __name__ == '__main__': print ("parent ", os.getpid()) while True: p = mp.Process(target = pro) p.start() time.sleep(1)
于是我覺得我要重新了解一下這個過程。
銷毀僵尸進程的時機
mutilprossing.Process 繼承自 BaseProcess 文件在 Lib/mutilprossing/process.py 中,我們看看它的start方法:
_children = set() class BaseProcess(object): def start(self): self._check_closed() _cleanup() self._popen = self._Popen(self) self._sentinel = self._popen.sentinel # Avoid a refcycle if the target function holds an indirect # reference to the process object (see bpo-30775) del self._target, self._args, self._kwargs _children.add(self)
_children 是一個全局的集合變量,保存著所有 BaseProcess 實例, start 函數(shù)末尾處 _children.add(self) 將進程對象放入。又注意到 _cleanup() 函數(shù):
def _cleanup(): # check for processes which have finished for p in list(_children): if p._popen.poll() is not None: _children.discard(p)
_popen 是一個 Popen 對象,代碼在 multiprossing/popen_fork.py 中,其 poll 函數(shù)有個 id, sts = os.waitpid(self.pid, flag) 一個回收子進程的函數(shù)?;厥蘸笤賹?BaseProcess 子類實例從_children中移除。
這下就清楚了,python在子進程start中將進程放入集合,子進程可能長時間運行,因此這個集合上的進程會有很多狀態(tài),而為了防止過多僵尸進程導致資源占用,python會在下一個子進程 start 時清理僵尸進程。所以,最后一個子進程在自身程序運行完畢后就變成僵尸進程,它在等待下一個子進程start時被清理。所以 ps 上總有一個僵尸進程,但這個僵尸進程的 進程id 一直在變化。
相關(guān)文章
Pycharm中切換pytorch的環(huán)境和配置的教程詳解
這篇文章主要介紹了Pycharm中切換pytorch的環(huán)境和配置,本文給大家介紹的非常詳細,對大家的工作或?qū)W習具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03Python之a(chǎn)scii轉(zhuǎn)中文的實現(xiàn)
這篇文章主要介紹了Python之a(chǎn)scii轉(zhuǎn)中文的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-05-05Python Django中間件,中間件函數(shù),全局異常處理操作示例
這篇文章主要介紹了Python Django中間件,中間件函數(shù),全局異常處理操作,結(jié)合實例形式分析了Django中間件,中間件函數(shù),全局異常處理相關(guān)操作技巧,需要的朋友可以參考下2019-11-11Python機器學習之K-Means聚類實現(xiàn)詳解
這篇文章主要為大家詳細介紹了Python機器學習之K-Means聚類的實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-02-02