python清理子进程机制剖析

yipeiwu_com7年前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 一直在变化。

相关文章

详解Django中间件执行顺序

详解Django中间件执行顺序

中间件 Django中的中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出。中间件的设计为开发者提供了一种无侵入式的开发方式,增强...

python 利用pywifi模块实现连接网络破解wifi密码实时监控网络

python 利用pywifi模块实现连接网络破解wifi密码实时监控网络,具体内容如下: import pywifi from pywifi import * import tim...

详解详解Python中writelines()方法的使用

 writelines()方法写入字符串序列到文件。该序列可以是任何可迭代的对象产生字符串,字符串为一般列表。没有返回值。 语法 以下是writelines()方法的语法:...

python使用nntp读取新闻组内容的方法

本文实例讲述了python使用nntp读取新闻组内容的方法。分享给大家供大家参考。具体实现方法如下: from nntplib import * s = NNTP('web.aioe...

Python编程实现及时获取新邮件的方法示例

本文实例讲述了Python编程实现及时获取新邮件的方法。分享给大家供大家参考,具体如下: #-*- encoding: utf-8 -*- import sys import loc...