像线程一样管理进程的Python multiprocessing库

一、创建一个进程

要创建一个进程,最简单的方式是用一个目标函数实例化一个Process对象,然后与threading一样调用start()函数让它工作。示例如下:

import multiprocessing

def worker():
    for i in range(3):
        print(i)

if __name__=="__main__":
    p = multiprocessing.Process(target=worker)
    p.start()

运行之后,效果如下:

需要注意的是,multiprocessing库在Windows创建进程必须在if __name__=="__main__":中,这是 Windows 上多进程的实现问题。在 Windows 上,子进程会自动 import 启动它的这个文件,而在 import 的时候是会执行这些语句的。如果直接创建就会无限递归创建子进程报错。所以必须把创建子进程的部分用那个 if 判断保护起来,import 的时候 __name__ 不是 __main__ ,就不会递归运行了。

二、设置进程名

在threading线程中,我们可以通过其参数name设置线程名,同样的我们也可以通过name参数设置其进程的名字。示例如下:

import multiprocessing
import time

def worker():
    print(multiprocessing.current_process().name, "start")
    time.sleep(2)
    print(multiprocessing.current_process().name, "end")

if __name__ == "__main__":
    p1 = multiprocessing.Process(name='p1', target=worker)
    p2 = multiprocessing.Process(name='p2', target=worker)
    p3 = multiprocessing.Process(name='p3', target=worker)
    p1.start()
    p2.start()
    p3.start()

运行之后,效果如下:

三、守护进程

和线程一样,在所有子进程没有退出之前,主程序是不会退出的。有时候,我们可能需要启动一个后台进程,它可以一直运行而不阻塞主程序退出。

要标志一个守护进程,可以将其添加第3个参数daemon,设置为True。默认值为False,不作为守护进程。示例如下:

import multiprocessing
import time

def worker():
    print(multiprocessing.current_process().name, "start")
    time.sleep(1)
    print(multiprocessing.current_process().name, "end")

def worker2():
    print(multiprocessing.current_process().name, "start")
    time.sleep(2)
    print(multiprocessing.current_process().name, "end")

if __name__ == "__main__":
    p1 = multiprocessing.Process(name='p1', target=worker)
    p2 = multiprocessing.Process(name='p2', target=worker2, daemon=True)
    p3 = multiprocessing.Process(name='p3', target=worker2, daemon=True)
    p1.start()
    p2.start()
    p3.start()

运行之后,效果如下:

p2,p3为守护进程,但p1不是所以执行1秒之后,就退出主程序了,也就没有打印p2p3的内容。但是其依旧在执行中,直到执行完成。

四、join()

同样的,如果你期望强制等待一个守护进程的结束,可以增加join()函数。还是上面的代码,示例如下:

import multiprocessing
import time

def worker():
    print(multiprocessing.current_process().name, "start")
    time.sleep(1)
    print(multiprocessing.current_process().name, "end")

def worker2():
    print(multiprocessing.current_process().name, "start")
    time.sleep(2)
    print(multiprocessing.current_process().name, "end")

if __name__ == "__main__":
    p1 = multiprocessing.Process(name='p1', target=worker)
    p2 = multiprocessing.Process(name='p2', target=worker2, daemon=True)
    p3 = multiprocessing.Process(name='p3', target=worker2, daemon=True)
    p1.start()
    p2.start()
    p3.start()
    p1.join()
    p2.join()
    p3.join()

运行之后,和设置进程名的运行结果一样,这里不在展示。唯一与守护进程代码的区别就是最后三行join()函数代码。当然,也可以像线程一样,给join()函数传入一个时间,超过这个时间,主进程不再等待。

五、强制结束进程

如果一个进程已经挂起或者不小心进入了死锁状态,那么这个时候,我们往往会强制的结束进程。对一个进程对象调用terminate()会结束子进程。示例如下:

import multiprocessing
import time

def worker():
    print(multiprocessing.current_process().name, "start")
    time.sleep(5)
    print(multiprocessing.current_process().name, "end")

if __name__ == "__main__":
    p1 = multiprocessing.Process(name='p1', target=worker)
    p1.start()
    print("是否还在运行", p1.is_alive())
    p1.terminate()
    print("是否还在运行", p1.is_alive())
    p1.join()
    print("是否还在运行", p1.is_alive())

运行之后,输出如下:

终止进程后要使用join()函数等待进程的退出。使进程管理代码有足够的时间更新对象的状态,以反应进程已经终止。

六、进程退出状态码

进程退出时,生成的状态码可以通过exitcode属性访问。下表就是其状态码的取值范围以及其意义:

退出码 含义
0 未生成任何错误
>0 进程有一个错误,并以该错误码退出
<0 进程以一个-1*exitcodde信号结束

测试如下:

import multiprocessing
import time

def worker():
    print(multiprocessing.current_process().name, "start")
    time.sleep(5)
    print(multiprocessing.current_process().name, "end")

if __name__ == "__main__":
    p1 = multiprocessing.Process(name='p1', target=worker)
    p2 = multiprocessing.Process(name='p2', target=worker)
    p1.start()
    p2.start()
    print("是否还在运行", p1.is_alive())
    p1.terminate()
    print("是否还在运行", p1.is_alive())
    print(p1.exitcode)
    p1.join()
    print("是否还在运行", p1.is_alive())
    print(p1.exitcode)
    time.sleep(5.5)
    print(p2.exitcode)

运行之后,效果如下:

可以看到,强制退出的进程状态码为负数,正常退出的进程状态码为0。

七、日志

调试并发问题时,如果能够访问multiprocessing所提供对象的内部状态,那么这会很有用。在实际的项目中,我们可以使用一个方便的模块级函数启用日志记录,它使用logging建立一个日志记录器对象,并增加一个处理器,使日志消息被发送到标准错误通道。

示例如下:

import multiprocessing
import logging
import sys

def worker():
    print("运行工作进程")
    sys.stdout.flush()

if __name__ == "__main__":
    multiprocessing.log_to_stderr(logging.DEBUG)
    p1 = multiprocessing.Process(name='p1', target=worker)
    p1.start()
    p1.join()

运行之后,效果如下:

八、派生进程

与线程一样,我们可以自定义进程,而不必只是传入一个函数进行进程的创建。

创建的进程的方式也是派生自进程类即可。示例如下:

import multiprocessing

class WorkerProcess(multiprocessing.Process):
    def run(self):
        print(self.name)
        return

if __name__ == "__main__":
    for i in range(5):
        p = WorkerProcess()
        p.start()
        p.join()

运行之后,效果如下:

multiprocessing库的进程知识与threading一样长,因为本篇的内容已经够长了,剩下的知识我们将在下一篇博文中接着讲解。

到此这篇关于像线程一样管理进程的Python multiprocessing库的文章就介绍到这了,更多相关Python multiprocessing库内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python数据可视化常用4大绘图库原理详解

    今天我们就用一篇文章,带大家梳理matplotlib.seaborn.plotly.pyecharts的绘图原理,让大家学起来不再那么费劲! 1. matplotlib绘图原理 关于matplotlib更详细的绘图说明,大家可以参考下面这篇文章,相信你看了以后一定学得会. matplotlib绘图原理:http://suo.im/678FCo 1)绘图原理说明 通过我自己的学习和理解,我将matplotlib绘图原理高度总结为如下几步: 导库;创建figure画布对象;获取对应位置的axes坐标

  • Python数据可视化库seaborn的使用总结

    seaborn是python中的一个非常强大的数据可视化库,它集成了matplotlib,下图为seaborn的官网,如果遇到疑惑的地方可以到官网查看.http://seaborn.pydata.org/ 从官网的主页我们就可以看出,seaborn在数据可视化上真的非常强大. 1.首先我们还是需要先引入库,不过这次要用到的python库比较多. import numpy as np import pandas as pd import matplotlib as mpl import matpl

  • Python数据可视化处理库PyEcharts柱状图,饼图,线性图,词云图常用实例详解

    python可以在处理各种数据时,如果可以将这些数据,利用图表将其可视化,这样在分析处理起来,将更加直观.清晰,以下是 利用 PyEcharts 常用图表的可视化Demo, 开发环境 python3 柱状图 基本柱状图 from pyecharts import Bar # 基本柱状图 bar = Bar("基本柱状图", "副标题") bar.use_theme('dark') # 暗黑色主题 bar.add('真实成本', # label ["1月&q

  • python第三方库visdom的使用入门教程

    概述 Visdom:一个灵活的可视化工具,可用来对于 实时,富数据的 创建,组织和共享.支持Torch和Numpy还有pytorch. visdom 可以实现远程数据的可视化,对科学实验有很大帮助.我们可以远程的发送图片和数据,并进行在ui界面显示出来,检查实验结果,或者debug. 要用这个先要安装,对于python模块而言,安装都是蛮简单的: pip install visdom 安装完每次要用直接输入代码打开: python -m visdom.server 然后根据提示在浏览器中输入相应

  • Python数据可视化:顶级绘图库plotly详解

    有史以来最牛逼的绘图工具,没有之一 plotly是现代平台的敏捷商业智能和数据科学库,它作为一款开源的绘图库,可以应用于Python.R.MATLAB.Excel.JavaScript和jupyter等多种语言,主要使用的js进行图形绘制,实现过程中主要就是调用plotly的函数接口,底层实现完全被隐藏,便于初学者的掌握. 下面主要从Python的角度来分析plotly的绘图原理及方法: ###安装plotly: 使用pip来安装plotly库,如果机器上没有pip,需要先进行pip的安装,这里

  • python使用pyecharts库画地图数据可视化的实现

    python使用pyecharts库画地图数据可视化导库中国地图代码结果世界地图代码结果省级地图代码结果地级市地图代码结果 导库 from pyecharts import options as opts from pyecharts.charts import Map 中国地图 代码 data = [('湖北', 9074),('浙江', 661),('广东', 632),('河南', 493),('湖南', 463), ('安徽', 340),('江西', 333),('重庆', 275),

  • Python自动安装第三方库的小技巧(pip使用详解)

    大家好,我是才哥. 最近周末也加班了,害- 有刚接触python的粉丝同学在运行此前<>的完整代码遇到以下问题,然后- 好吧,今天我们就专门介绍一下Python安装第三方库的一些小技巧,其中还包含自动安装的方法哈. 1. pip在线安装 在cmd命令行模式下,通过pip install 第三方库名称的形式,直接进行第三方库的安装. 我们以安装plotly为例,安装表现如下: pip install plotly 如果需要安装的第三方库已经存在,我们执行安装命令的时候会提示其存在且展示库安装的位

  • Python数据可视化:箱线图多种库画法

    概念 箱线图通过数据的四分位数来展示数据的分布情况.例如:数据的中心位置,数据间的离散程度,是否有异常值等. 把数据从小到大进行排列并等分成四份,第一分位数(Q1),第二分位数(Q2)和第三分位数(Q3)分别为数据的第25%,50%和75%的数字. 四分位间距(Interquartilerange(IQR))=上分位数(upper quartile)-下分位数(lower quartile) 箱线图分为两部分,分别是箱(box)和须(whisker).箱(box)用来表示从第一分位到第三分位的数

  • Pytho常见的数据可视化库,小白必备

    一.Matplotlib Matplotlib是Python中众多数据可视化库的鼻祖,其设计风格与20世纪80年代设计的商业化程序语言MATLAB十分接近,具有很多强大且复杂的可视化功能.Matplotlib包含多种类型的API,可以采用多种方式绘制图表并对图表进行定制. 二.Seaborn Seaborn是基于Matplotlib进行高级封装的可视化库,它支持交互式界面,使绘制图表的功能变得更简单,且图表的色彩更具吸引力,可以画出丰富多样的统计图表. 三.ggplot ggplot是基于Mat

  • 能让你轻松的实现自然语言处理的5个Python库

    一.前言 自然语言是指人类相互交流的语言,而自然语言处理是将数据以可理解的形式进行预处理,使计算机能够理解的一种方法.简单地说,自然语言处理(NLP)是帮助计算机用自己的语言与人类交流的过程. 自然语言处理是最广泛的研究领域之一.许多大公司在这个领域投资很大.NLP为公司提供了机会,让他们能够根据消费者的情绪和文本很好地了解他们.NLP的一些最佳用例是检测假电子邮件.对假新闻进行分类.情感分析.预测你的下一个单词.自动更正.聊天机器人.个人助理等等. 解决任何NLP任务前要知道的7个术语 标记:

  • Python中threading库实现线程锁与释放锁

    控制资源访问 前文提到threading库在多线程时,对同一资源的访问容易导致破坏与丢失数据.为了保证安全的访问一个资源对象,我们需要创建锁. 示例如下: import threading import time class AddThread(): def __init__(self, start=0): self.lock = threading.Lock() self.value = start def increment(self): print("Wait Lock") se

  • 基于telepath库实现Python和JavaScript之间交换数据

    它有什么作用? 它提供了一种将包括Python对象在内的结构化数据打包为JSON可序列化格式的机制.通过向相应的JavaScript实现注册该机制,可以扩展该机制以支持任何Python类.然后,打包的数据可以包含在HTTP响应中,并在JavaScript中解压缩以获得与原始数据等效的数据结构. 安装方法 pip install telepath 并将'telepath'添加到项目的INSTALLED_APPS. 简介 假设我们正在构建一个用于玩跳棋的Django应用.我们已经花费了数天或数周的时

  • Python文件名的匹配之clob库

    一.前言 既然在Pathlib库中提到了glob()函数,那么我们就专门用一篇内容讲解文件名的匹配.其实我们有专门的一个文件名匹配库就叫:glob. 不过,glob库的API非常小,但是仅仅应用于文件名的匹配绰绰有余.只要是在实际的项目中需要过滤,或者匹配一组文件,都可以使用该库进行操作. 二.通配符 星号(*) 话不多说,下面我们使用通配符来匹配文件名,示例如下: import glob for name in sorted(glob.glob('text/*')): print(name)

随机推荐