第52天:Python multiprocessing 模块

简介: 第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合集

目录
相关文章
|
25天前
|
开发者 Python
如何在Python中管理模块和包的依赖关系?
在实际开发中,通常会结合多种方法来管理模块和包的依赖关系,以确保项目的顺利进行和可维护性。同时,要及时更新和解决依赖冲突等问题,以保证代码的稳定性和可靠性
42 4
|
5天前
|
Python
Python Internet 模块
Python Internet 模块。
100 74
|
23天前
|
算法 数据安全/隐私保护 开发者
马特赛特旋转算法:Python的随机模块背后的力量
马特赛特旋转算法是Python `random`模块的核心,由松本真和西村拓士于1997年提出。它基于线性反馈移位寄存器,具有超长周期和高维均匀性,适用于模拟、密码学等领域。Python中通过设置种子值初始化状态数组,经状态更新和输出提取生成随机数,代码简单高效。
104 63
|
24天前
|
测试技术 Python
手动解决Python模块和包依赖冲突的具体步骤是什么?
需要注意的是,手动解决依赖冲突可能需要一定的时间和经验,并且需要谨慎操作,避免引入新的问题。在实际操作中,还可以结合使用其他方法,如虚拟环境等,来更好地管理和解决依赖冲突😉。
|
24天前
|
持续交付 Python
如何在Python中自动解决模块和包的依赖冲突?
完全自动解决所有依赖冲突可能并不总是可行,特别是在复杂的项目中。有时候仍然需要人工干预和判断。自动解决的方法主要是提供辅助和便捷,但不能完全替代人工的分析和决策😉。
|
1月前
|
JSON Linux 数据格式
Python模块:从入门到精通,只需一篇文章!
Python中的模块是将相关代码组织在一起的单元,便于重用和维护。模块可以是Python文件或C/C++扩展,Python标准库中包含大量模块,如os、sys、time等,用于执行各种任务。定义模块只需创建.py文件并编写代码,导入模块使用import语句。此外,Python还支持自定义模块和包,以及虚拟环境来管理项目依赖。
Python模块:从入门到精通,只需一篇文章!
|
25天前
|
Python
Python的模块和包
总之,模块和包是 Python 编程中非常重要的概念,掌握它们可以帮助我们更好地组织和管理代码,提高开发效率和代码质量
37 5
|
24天前
|
数据可视化 Python
如何在Python中解决模块和包的依赖冲突?
解决模块和包的依赖冲突需要综合运用多种方法,并且需要团队成员的共同努力和协作。通过合理的管理和解决冲突,可以提高项目的稳定性和可扩展性
|
1月前
|
Python
在Python中,可以使用内置的`re`模块来处理正则表达式
在Python中,可以使用内置的`re`模块来处理正则表达式
46 5
|
1月前
|
Java 程序员 开发者
Python的gc模块
Python的gc模块
下一篇
DataWorks