python清理子进程机制剖析

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

相关文章

python生成日历实例解析

本文实例展示了Python生成日历的实现方法。该实例可实现一个月的日历生成5x7的列表,列表里的没个日期为datetime类型,采用python自带的 calendar 模块实现。 程序...

Pythony运维入门之Socket网络编程详解

Pythony运维入门之Socket网络编程详解

Socket是什么? Socket 是电脑网络中进程间数据流的端点Socket 是操作系统的通信机制应用程序通过Socket进行网络数据的传输 首先,简单了解一下TCP通信过程: TC...

python3.x+pyqt5实现主窗口状态栏里(嵌入)显示进度条功能

python3.x+pyqt5实现主窗口状态栏里(嵌入)显示进度条功能

1、代码1: (1)进度条等显示在主窗口状态栏的右端,代码如下: from PyQt5.QtWidgets import QMainWindow, QProgressBar, QAp...

解决Pyinstaller 打包exe文件 取消dos窗口(黑框框)的问题

解决Pyinstaller 打包exe文件 取消dos窗口(黑框框)的问题

我们用python 打包的exe文件的时候,每次运行后面都有一个黑框框,比如我的这个: 用tkinter做的图形界面,打包成exe文件,每次运行都先有黑色框框,我们一般电脑用的带有图形...

python3使用urllib示例取googletranslate(谷歌翻译)

复制代码 代码如下:#!/usr/bin/env python3# -*- coding: utf-8 -*-# File Name : gt1.py# Purpose :# Creat...