简单学习Python多进程Multiprocessing
发布时间 - 2026-01-11 03:01:07 点击率:次1.1 什么是 Multiprocessing

多线程在同一时间只能处理一个任务。
可把任务平均分配给每个核,而每个核具有自己的运算空间。
1.2 添加进程 Process
与线程类似,如下所示,但是该程序直接运行无结果,因为IDLE不支持多进程,在命令行终端运行才有结果显示
import multiprocessing as mp
def job(a,b):
print('abc')
if __name__=='__main__':
p1=mp.Process(target=job,args=(1,2))
p1.start()
p1.join()
1.3 存储进程输出 Queue
不知道为什么下面的这个程序可以在IDLE中正常运行。首先定义了一个job函数作系列数学运算,然后将结果放到res中,在main函数运行,取出queue中存储的结果再进行一次加法运算。
import multiprocessing as mp def job(q): res=0 for i in range(1000): res+=i+i**2+i**3 q.put(res) if __name__ == '__main__': q=mp.Queue() p1 = mp.Process(target=job,args=(q,))#注意当参数只有一个时,应加上逗号 p2 = mp.Process(target=job,args=(q,)) p1.start() p2.start() p1.join() p2.join() res1=q.get() res2=q.get() print(res1+res2)
结果如下所示:
1.4 效率比对 threading & multiprocessing
在job函数中定义了数学运算,比较正常情况、多线程和多进程分别的运行时间。
import multiprocessing as mp
import threading as td
import time
def job(q):
res = 0
for i in range(10000000):
res += i+i**2+i**3
q.put(res) # queue
def multicore():
q = mp.Queue()
p1 = mp.Process(target=job, args=(q,))
p2 = mp.Process(target=job, args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
res1 = q.get()
res2 = q.get()
print('multicore:' , res1+res2)
def normal():
res = 0
for _ in range(2):#线程或进程都构造了两个,进行了两次运算,所以这里循环两次
for i in range(10000000):
res += i+i**2+i**3
print('normal:', res)
def multithread():
q = mp.Queue()
t1 = td.Thread(target=job, args=(q,))
t2 = td.Thread(target=job, args=(q,))
t1.start()
t2.start()
t1.join()
t2.join()
res1 = q.get()
res2 = q.get()
print('multithread:', res1+res2)
if __name__ == '__main__':
st = time.time()
normal()
st1= time.time()
print('normal time:', st1 - st)
multithread()
st2 = time.time()
print('multithread time:', st2 - st1)
multicore()
print('multicore time:', time.time()-st2)
在视频中的运行结果是多进程<正常<多线程,而我的运行结果为下图所示:
综上,多核/多进程运行最快,说明在同时间运行了多个任务,而多线程却不一定会比正常情况下的运行来的快,这和多线程中的GIL有关。
1.5 进程池
进程池Pool,就是我们将所要运行的东西,放到池子里,Python会自行解决多进程的问题。
import multiprocessing as mp def job(x): return x*x def multicore(): pool=mp.Pool(processes=2)#定义一个Pool,并定义CPU核数量为2 res=pool.map(job,range(10)) print(res) res=pool.apply_async(job,(2,)) print(res.get()) multi_res=[pool.apply_async(job,(i,)) for i in range(10)] print([res.get()for res in multi_res]) if __name__=='__main__': multicore()
运行结果如下所示:
首先定义一个池子,有了池子之后,就可以让池子对应某一个函数,在上述代码中定义的pool对应job函数。我们向池子里丢数据,池子就会返回函数返回的值。 Pool和之前的Process的不同点是丢向Pool的函数有返回值,而Process的没有返回值。
接下来用map()获取结果,在map()中需要放入函数和需要迭代运算的值,然后它会自动分配给CPU核,返回结果
我们怎么知道Pool是否真的调用了多个核呢?我们可以把迭代次数增大些,然后打开CPU负载看下CPU运行情况
打开CPU负载(Mac):活动监视器 > CPU > CPU负载(单击一下即可)
Pool默认大小是CPU的核数,我们也可以通过在Pool中传入processes参数即可自定义需要的核数量。
Pool除了可以用map来返回结果之外,还可以用apply_async(),与map不同的是,只能传递一个值,只会放入一个核进行计算,但是传入值时要注意是可迭代的,所以在传入值后需要加逗号, 同时需要用get()方法获取返回值。所对应的代码为:
res=pool.apply_async(job,(2,)) print(res.get())
运行结果为4。
由于传入值是可以迭代的,则我们同样可以使用apply_async()来输出多个结果。如果在apply_async()中输入多个传入值:
res = pool.apply_async(job, (2,3,4,))
结果会报错:
TypeError: job() takes exactly 1 argument (3 given)
即apply_async()只能输入一组参数。
在此我们将apply_async()放入迭代器中,定义一个新的multi_res
multi_res = [pool.apply_async(job, (i,)) for i in range(10)]
同样在取出值时需要一个一个取出来
print([res.get() for res in multi_res])
apply用迭代器的运行结果与map取出的结果相同。
note:
(1)Pool默认调用是CPU的核数,传入processes参数可自定义CPU核数
(2)map() 放入迭代参数,返回多个结果
(3)apply_async()只能放入一组参数,并返回一个结果,如果想得到map()的效果需要通过迭代
1.6 共享内存 shared memory
只有通过共享内存才能让CPU之间进行交流。
通过Value将数据存储在一个共享的内存表中。
import multiprocessing as mp
value1 = mp.Value('i', 0)
value2 = mp.Value('d', 3.14)
其中,i和d表示数据类型。i为带符号的整型,d为双精浮点类型。更多数据类型可参考网址:https://docs.python.org/3/library/array.html
在多进程中有一个Array类,可以和共享内存交互,来实现进程之间共享数据。
和numpy中的不同,这里的Array只能是一维的,并且需要定义数据类型否则会报错。
array = mp.Array('i', [1, 2, 3, 4])
1.7 进程锁 Lock
首先是不加进程锁的运行情况,在下述代码中定义了共享变量v,定义了两个进程,均可对v进行操作。job函数的作用是每隔0.1s输出一次累加num的值,累加值num在两个进程中分别为1和3。
import multiprocessing as mp
import time
def job(v,num):
for _ in range(10):
time.sleep(0.1)#暂停0.1s,让输出效果更明显
v.value+=num #v.value获取共享变量值
print(v.value)
def multicore():
v=mp.Value('i',0)#定义共享变量
p1=mp.Process(target=job,args=(v,1))
p2=mp.Process(target=job,args=(v,3))
p1.start()
p2.start()
p1.join()
p2.join()
if __name__=='__main__':
multicore()
运行结果如下所示:
可以看到两个进程互相抢占共享内存v。
为了解决上述不同进程抢共享资源的问题,我们可以用加进程锁来解决。
首先需要定义一个进程锁:
l = mp.Lock() # 定义一个进程锁
然后将进程锁的信息传入各个进程中
p1 = mp.Process(target=job, args=(v,1,l)) # 需要将Lock传入 p2 = mp.Process(target=job, args=(v,3,l))
在job()中设置进程锁的使用,保证运行时一个进程的对锁内内容的独占
def job(v, num, l): l.acquire() # 锁住 for _ in range(5): time.sleep(0.1) v.value += num # v.value获取共享内存 print(v.value) l.release() # 释放
完整代码:
def job(v, num, l):
l.acquire() # 锁住
for _ in range(5):
time.sleep(0.1)
v.value += num # 获取共享内存
print(v.value)
l.release() # 释放
def multicore():
l = mp.Lock() # 定义一个进程锁
v = mp.Value('i', 0) # 定义共享内存
p1 = mp.Process(target=job, args=(v,1,l)) # 需要将lock传入
p2 = mp.Process(target=job, args=(v,3,l))
p1.start()
p2.start()
p1.join()
p2.join()
if __name__ == '__main__':
multicore()
运行结果如下所示:
可以看到进程1运行完之后才运行进程2。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# Python
# 多进程
# Multiprocessing
# Python多进程并发(multiprocessing)用法实例详解
# Python3多进程 multiprocessing 模块实例详解
# Python多进程multiprocessing用法实例分析
# python multiprocessing多进程变量共享与加锁的实现
# Python标准库之多进程(multiprocessing包)介绍
# python基于multiprocessing的多进程创建方法
# python multiprocessing 多进程并行计算的操作
# Python使用multiprocessing实现多进程的详细步骤记录
# 多个
# 所示
# 迭代
# 多线程
# 可以用
# 返回值
# 两次
# 可以看到
# 自定义
# 多核
# 报错
# 锁住
# 自己的
# 的是
# 就会
# 浮点
# 在此
# 中有
# 我们可以
# 只会
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
网站建设保证美观性,需要考虑的几点问题!
Laravel怎么在Controller之外的地方验证数据
Microsoft Edge如何解决网页加载问题 Edge浏览器加载问题修复
laravel怎么在请求结束后执行任务(Terminable Middleware)_laravel Terminable Middleware请求结束任务执行方法
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
Laravel 419 page expired怎么解决_Laravel CSRF令牌过期处理
Android自定义控件实现温度旋转按钮效果
,南京靠谱的征婚网站?
Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程
如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?
C#如何调用原生C++ COM对象详解
简历在线制作网站免费版,如何创建个人简历?
php静态变量怎么调试_php静态变量作用域调试技巧【解答】
如何用好域名打造高点击率的自主建站?
高端建站三要素:定制模板、企业官网与响应式设计优化
如何在阿里云香港服务器快速搭建网站?
网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?
香港服务器网站卡顿?如何解决网络延迟与负载问题?
三星、SK海力士获美批准:可向中国出口芯片制造设备
INTERNET浏览器怎样恢复关闭标签页_INTERNET浏览器标签恢复快捷键与方法【指南】
如何在企业微信快速生成手机电脑官网?
Laravel项目怎么部署到Linux_Laravel Nginx配置详解
车管所网站制作流程,交警当场开简易程序处罚决定书,在交警网站查询不到怎么办?
详解vue.js组件化开发实践
Java遍历集合的三种方式
太平洋网站制作公司,网络用语太平洋是什么意思?
Laravel如何为API编写文档_Laravel API文档生成与维护方法
Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】
高性价比服务器租赁——企业级配置与24小时运维服务
Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】
如何在 Pandas 中基于一列条件计算另一列的分组均值
Laravel storage目录权限问题_Laravel文件写入权限设置
Win11搜索栏无法输入_解决Win11开始菜单搜索没反应问题【技巧】
Laravel如何配置.env文件管理环境变量_Laravel环境变量使用与安全管理
百度浏览器ai对话怎么关 百度浏览器ai聊天窗口隐藏
做企业网站制作流程,企业网站制作基本流程有哪些?
如何快速使用云服务器搭建个人网站?
Laravel如何使用.env文件管理环境变量?(最佳实践)
HTML5打空格有哪些误区_新手常犯的空格使用错误【技巧】
Laravel怎么实现模型属性的自动加密
Python自然语言搜索引擎项目教程_倒排索引查询优化案例
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
在线制作视频网站免费,都有哪些好的动漫网站?
如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体
Laravel的.env文件有什么用_Laravel环境变量配置与管理详解
如何用wdcp快速搭建高效网站?
如何正确选择百度移动适配建站域名?
Laravel怎么连接多个数据库_Laravel多数据库连接配置
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
Python数据仓库与ETL构建实战_Airflow调度流程详解

