1. 程式人生 > >python清理子程序機制剖析

python清理子程序機制剖析

python的機制會自動清理已經完成任務的子程序的,下面通過本文給大家分享python清理子程序機制剖析,需要的朋友參考下吧

起步

在我的印象中,python的機制會自動清理已經完成任務的子程序的。通過網友的提問,還真看到了殭屍程序。

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 函式末尾處 _children.add(self) 將程序物件放入。又注意到 _cleanup() 函式:

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 函式有個 id, sts = os.waitpid(self.pid, flag) 一個回收子程序的函式。回收後再將 BaseProcess 子類例項從_children中移除。

這下就清楚了,python在子程序start中將程序放入集合,子程序可能長時間執行,因此這個集合上的程序會有很多狀態,而為了防止過多殭屍程序導致資源佔用,python會在下一個子程序 start 時清理殭屍程序。所以,最後一個子程序在自身程式執行完畢後就變成殭屍程序,它在等待下一個子程序start時被清理。所以 ps 上總有一個殭屍程序,但這個殭屍程序的 程序id 一直在變化。

出處:https://www.jb51.net/article/128913.htm