第52天:Python multiprocessing 模块

本节主要介绍 multiprocessing 多进程模块,由于 threading 多线程模块无法充分利用电脑的多核优势,而在实际开发中会对系统性能有较高的要求,就需要使用多进程来充分利用多核 cpu 的资源,下面详细介绍 Python 中的 multiprocessing。

multiprocessing 多进程模块有类似 threading 模块的 API 接口,方便熟悉 threading 的用户直接使用 multiprocessing。它支持子进程、通信和共享数据、执行不同形式的同步,下面简单介绍下几个常用的组件。

Process类

在 multiprocessing 中生成进程的方式是通过创建一个 Process 对象,然后调用它的 start() 方法来实现。例如:

from multiprocessing import Processdef f(name): print('hello', name)if __name__ == '__main__': p = Process(target=f, args=('world',)) #启动进程 p.start() #实现进程间的同步,等待所有进程退出 p.join()
#执行结果:hello world

需要注意的是,在上面示例代码中使用了if __name__ == '__main__',这行代码是符合编程规范的。加上它可以确保主模块能够被新启动的 Python 解释器安全导入。

在启动进程的过程中,需要考虑执行顺序的问题,正常情况下是主进程先执行,子进程后执行。例如:

#主子进程执行顺序from multiprocessing import Processimport osimport timedef run(): print("子进程开启") time.sleep(2) print("子进程结束")
if __name__ == "__main__": print("主进程启动") p = Process(target=run) p.start() print("主进程结束")
#执行结果:主进程启动主进程结束子进程开启子进程结束

Queue类

因为不同进程之间内存是不共享的,要想实现进程间的通信,必须要提供中间的媒介。Python 提供了两个通信的对象类。一个是 Queue 类,另一个是 Pipe 类。

Queue 队列使用一个管道和少量锁和信号量实现的共享队列实例,它是线程和进程安全的,常被用于两个进程之间的通讯。例如有一个 wirte 进程负责写数据,另外一个 read 进程负责读数据。当我们需要将写的数据交给读的进程时,可以通过 Queue 作为中间桥梁,先把 write 进程写的数据交给队列,再由队列将数据传递给 read 进程。

#Queue队列from multiprocessing import Process, Queuedef f(q): q.put([11, None, 'lily'])if __name__ == '__main__': q = Queue() p = Process(target=f, args=(q,)) p.start() print(q.get()) p.join()
#执行结果:[11, None, 'lily']

在上述示例中调用了 join()函数,它可以阻塞主进程,直到调用 join()函数的进程终止。该函数有一个可选的参数 timeout,参数 timeout 的默认值是 None。如果 timeout 是一个正数,它最多会阻塞 timeout 秒。

Pipe类

Pipe 和 Queue 一样,可以作为进程之间通信的通道。Pipe()函数返回两个对象 conn1conn2 ,这两个对象表示管道的两端。

Pipe()函数有一个可选参数 duplex,参数 duplex 的默认值为 True,表示该管道是双向的,即两个对象都可以发送和接收消息。如果把参数 duplex 设置为 False ,表示该管道是单向的,即 conn1 只能用于接收消息,conn2 只能用于发送消息。例如:

from multiprocessing import Process, Pipedef f(conn): conn.send([11, None, 'lily']) conn.close()
if __name__ == '__main__': conn1, conn2 = Pipe() p = Process(target=f, args=(conn2,)) p.start() print(conn1.recv()) p.join()
#执行结果:[11, None, 'lily']

从以上示例可以看出,Queue 和 Pipe 拥有相似的功能。但在日常开发中,两者使用的场景有所不同,Pipe 多用于两个进程间通信,而 Queue 则多用于两个及以上进程间的通信。

Lock类

由于多线程共享进程的资源和地址空间,因此,在对这些公共资源进行操作时,为了防止这些公共资源出现异常的结果,必须考虑线程的同步和互斥问题。

为了保证进程间的同步,我们可以使用 Lock 类给线程或者进程加锁。Lock 返回的是一个非递归锁对象,Lock 实际上是一个工厂函数。它返回由默认上下文初始化的 multiprocessing.synchronize.Lock 对象。

一旦某一个进程或者线程拿到了锁,后续的任何其他进程或线程的其他请求都会被阻塞直到锁被释放。例如:

#!/usr/bin/python3from multiprocessing import Process, Lockdef f(l, i): l.acquire() try: print('this is', i) finally: l.release()
if __name__ == '__main__': lock = Lock()
for num in range(10): Process(target=f, args=(lock, num)).start()
#执行结果:this is 0this is 2this is 3this is 4this is 1this is 5this is 6this is 7this is 8this is 9

总结

本节给大家介绍了 Python 中 multiprocessing 模块的常用操作,对于实现基于进程的并行操作提供了支撑,注意与 threading 模块基于线程的并行操作区分开。

示例代码:https://github.com/JustDoPython/python-100-day/tree/master/day-052

参考

[1] https://docs.python.org/3.7/library/multiprocessing.html

[2] https://blog.csdn.net/brucewong0516/article/details/85796073

系列文章

第51天:Python Queue 入门

第50天:Python Queue 进阶用法

第49天:Python 多线程之 threading 模块

第48天:初识 Python 多线程

第47天:Web 开发 RESTful

    第46天:Flask数据持久化

第45天:Web表单

第44天:Flask 框架集成Bootstrap

第43天:Python filecmp&difflib模块

第42天:Python paramiko 模块

第41天:Python operator 模块

第0-40天:从0学习Python 0-40合集

(0)

相关推荐

  • 一篇文章带你解析Python进程

    来源|本文经授权转载自Python爬虫与数据挖掘 前言 进程,一个新鲜的字眼,可能有些人并不了解,它是系统某个运行程序的载体,这个程序可以有单个或者多个进程,一般来说,进程是通过系统CPU 内核数来分 ...

  • (1条消息) Python 多进程 multiprocessing.Pool类详解

    multiprocessing模块 multiprocessing包是Python中的多进程管理包.它与 threading.Thread类似,可以利用multiprocessing.Process对 ...

  • python笔记46-史上最强大最好用的python日志模块nb_log

    前言 python的日志模块如何封装一值都是一个头疼的问题,封装的不好总是会出现重复打印等头疼问题. 现在终于找到一个最好用的日志模块nb_log,此日志模块由这位大佬开发的https://www.c ...

  • python random模块

    本篇介绍比较常用的一个标准模块,random. 这是一个随机数模块,可以用来随机生成随机数,经常被用于数学.游戏.算法等等上面. 1.导入random模块 要使用此模块,要先导入. import ra ...

  • python logging模块的几点总结

    http://www.voidcn.com/article/p-ctmbnbwp-bbo.html 关于使用python logging模块的几点总结 使用python的标准日志模块logging可以 ...

  • 第26天:Python os 模块详解

    第26天:Python os 模块详解

  • 第27天:Python shutil 模块

    shutil 可以看作 sh + util,即 shell 工具之意,该模块提供了一些针对文件和文件夹的高级操作,如:拷贝.删除.移动等,shutil 模块是对 os 模块的补充. 1 文件和文件夹操 ...

  • 第29天:Python queue 模块详解

    queue 模块即队列,特别适合处理信息在多个线程间安全交换的多线程程序中.下面我们对 queue 模块进行一个详细的使用介绍. 1 queue 模块定义的类和异常 queue 模块定义了以下四种不同 ...

  • 第30天:Python collections 模块

    第30天:Python collections 模块

  • 第31天:Python random 模块

    在本节中继续介绍 Python 提供的常用模块 random 模块,它的主要功能是用来生成伪随机数的. random 模块 Python 提供的 random 模块实现了各种分布式的伪随机数生成器.该 ...

  • 第32天:Python logging 模块详解

    This module defines functions and classes which implement a flexible event logging system for applic ...