Python 之并发编程之manager与进程池pool
一.manager
常用的数据类型:dict list 能够实现进程之间的数据共享
进程之间如果同时修改一个数据,会导致数据冲突,因为并发的特征,导致数据更新不同步。
def work(dic, lock):
# 简写:使用with语法自动给你上锁和解锁
with lock:
dic["count"] -= 1
'''
#上锁的正常写法
#上锁
lock.acquire()
#数据值减一
dic["conut"] -=1
# 解锁
lock.release()
'''
if __name__ == "__main__":
# 创建Manager对象
m = Manager()
# 创建一个锁对象(为了保证数据的同步)
lock = Lock()
lst = []
# 创建共享字典
dic = m.dict({"count": 100})
# 产生一百个进程。每个进程减一。
for i in range(100):
# 返回进程对象p
p = Process(target=work, args=(dic, lock))
p.start()
lst.append(p)
for i in lst:
i.join()
print(dic)
二.进程池pool
小知识点:
import os
# 计算你的机器有多少cpu
print(os.cpu_count())
1.比较pool 和Process 执行的速度
因为进程池可以实现并行的概念,比process单核并发的速度快
def func(num):
# time.sleep(3)
# time.sleep(random.uniform(0.1,1))
print("这是发送的第%d邮件" % (num))
if __name__ == "__main__":
startime = time.time()
# (1)进程池实现并行
# 创建进程对象
# pool() 里面的参数是同一个时间允许多少个进程并行
'''
4个任务
(1)1个人做4个
(2)4个人做4个
(3)4个人做1个
任务量较少时,3的速度较快,任务量较大时,2的速度更快.
因为如果任务线拉长,频繁切换cpu会占点时间.
'''
p = Pool() #默认是电脑cpu的核数,默认的时候任务量大更好
# 1 的时候 0.2560138702392578,如果是1表示电脑核数同时执行1个进程
# 不停的更换cpu运行进程任务,这样避免cpu过热降频
for i in range(100):
p.apply_async(func, args=(i,))
# 关闭进程池,不在接收新的进程
p.close()
# 主进程阻塞,等待子进程全部完成后再退出
p.join()
endtime = time.time()
print(endtime - startime) # 0.43866443634033203
# (2) Process 单核并发程序
startime = time.time()
lst = []
for i in range(100):
p = Process(target=func,args=(i,))
p.start()
lst.append(p)
for i in lst:
i.join()
endtime = time.time()
print(endtime-startime) # 8.061640739440918
2.apply 开启进程(未来可能去掉)
同步阻塞,每次都要等待当前任务完成之后,在开启下一个进程,可加上返回值。
def task(num):
time.sleep(random.uniform(0.1,1)) # 同步程序
print("%s:%s" % (num,os.getpid()))
return num
if __name__ == "__main__":
p = Pool()
for i in range(20):
res = p.apply(task,args=(i,))
print("-->",res)
# 完完全全的同步程序,等上面走完了再执行finish
print("finish")
同一时间只有4个进程。
3.apply_async 异步非阻塞程序 可以有返回值
Process 产生的子进程,默认主进程等待所有子进程执行完毕之后再终止
而Pool进程池,只要主进程跑完了,立刻终止所有程序
未来避免还没有执行就结束,进程time.sleep 和使用join守护。
例:
def task(num):
#time.sleep(3)
time.sleep(random.uniform(0.1,1)) #同步程序
print("%s:%s" %(num,os.getpid()))
return os.getpid()
if __name__ == "__main__":
p = Pool()
lst = []
lst2 = []
for i in range(20):
res = p.apply_async(task,args=(i,)) # res 是对象
# print(res)
# 1.把返回的对象一个一个插入到列表里
lst.append(res)
for i in lst:
# 2.使用get方法获取返回值
lst2.append(i.get())
# 关闭进程池.不在接受新的进程
p.close()
# 主进程阻塞,等待 子进程全部完成后再退出
p.join()
# 主进程阻塞,等待进程全部完成后再退出
# 返回的是默认 4个进程,因为当期机器是4个核心cpu
print(set(lst2),len(set(lst2)))
print("finish")
4.进程池.map
(与高阶函数map使用方法一样,只不过该map支持并行并发)
# 进程池.map 返回的是列表
# map默认底层中加了阻塞,等全部执行完毕之后,主进程在终止程序,区别于3
例:
if __name__ == "__main__":
p = Pool()
lst = p.map(task, range(100))
print(lst)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116, 2209, 2304, 2401, 2500, 2601, 2704, 2809, 2916, 3025, 3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969, 4096, 4225, 4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625, 5776, 5929, 6084, 6241, 6400, 6561, 6724, 6889, 7056, 7225, 7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, 9216, 9409, 9604, 9801]
# 如果出现了join,一定需要加上close,要么同时出现,要么都没有
# p.close()
# p.join()
print(123455)
5.关闭进程池
关闭进程池,不会再接受新的进程
例:
def task(num):
time.sleep(random.uniform(0.1,1))
print("%s:%s" % (num,os.getpid()))
return num ** 2
if __name__ == "__main__":
p = Pool()
lst= []
for i in range(20):
res = p.apply_async(task,args=(i,))
lst.append(res)
# get 函数内部默认加了阻塞,获取完所有值之后再向下执行
for i in lst:
print(i.get())
p.close()
# 如果执行close,不能够继续往进程池里面加进程了
# res = p.apply_async(task,args=(112233,))
p.join()
print("finish")
去掉程序例: # res = p.apply_async(task,args=(112233,))的注释就出现想要的结果:
转载于:https://www.cnblogs.com/hszstudypy/p/11222612.html
Python 之并发编程之manager与进程池pool相关推荐
- cyclicbarrier java_Java并发编程之CyclicBarrier和线程池的使用
原标题:Java并发编程之CyclicBarrier和线程池的使用 下面我们来讲述一下线程池和CyclicBarrier的使用和对比. 一.场景描述 有四个游戏玩爱好者玩游戏,游戏中有三个关卡,每一个 ...
- Python进阶:并发编程之Asyncio
什么是Asyncio 多线程有诸多优点且应用广泛,但也存在一定的局限性: 比如,多线程运行过程容易被打断,因此有可能出现 race condition 的情况:再如,线程切换本身存在一定的损耗,线程数 ...
- python并发编程之semaphore(信号量)_python 之 并发编程(守护进程、互斥锁、IPC通信机制)...
9.5 守护进程 主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就立即终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic process ...
- python电路模型编程_14、python开发之路-并发编程之I/O模型
十四.并发编程之I/O模型 http://www.cnblogs.com/linhaifeng/articles/7454717.html 1.模型介绍 1.1 IO种类 (1)* blocking ...
- Python并发编程之threading模块
Python并发编程之threading模块 threading 模块 1. Timer对象 2. Lock对象 3. RLock 4. 信号量和有边界的信号量 5. 事件 6. 条件变量 7. 使用 ...
- python 进程池 freeze_support_Python 多进程并发操作中进程池Pool的实例
在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间.当被操作对象数目不大时,可以直接利用multiprocessing中的Process ...
- python进程池调用实例方法_Python 多进程并发操作中进程池Pool的实例
在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间.当被操作对象数目不大时,可以直接利用multiprocessing中的Process ...
- java线程安全的set_Java并发编程之set集合的线程安全类你知道吗
Java并发编程之-set集合的线程安全类 Java中set集合怎么保证线程安全,这种方式你知道吗? 在Java中set集合是 本篇是<凯哥(凯哥并发编程学习>系列之<并发集合系列& ...
- python flask高级编程之restful_('Python Flask高级编程之RESTFul API前后端分离精讲',),全套视频教程学习资料通过百度云网盘下载...
资源详情 r n t某课网好评度100%的Python Flask高级编程之RESTFul API前后端分离精讲 r n t t t第1章 随便聊聊 r n t t t聊聊Flask与Django,聊 ...
最新文章
- xmarin.android导航栏,android – 如何在xamarin表单中更改导航页面后退按钮
- 2019-2021年中国AI芯片市场预测与展望数据
- 排除hotnews主题内容页面上的热点图片推荐里的分类-hotnews主题top_hot.php
- unity3D 4.6及以上版本. UI穿透问题,以及模拟器不穿透真机穿透问题解决方案
- python通过pyinstaller打包软件将GUI项目打包成exe文件
- 查找SAP所有事物代码及用处的几个方法
- SQLite的ADO.NET Provider支持ADO.NET Entity Framework
- JDBC基础学习(三)—处理BLOB类型数据
- Java技术:项目构建工具Maven最佳替代者gradle介绍
- RabbitMq入门(七)消息处理(消息持久化autoDelete、消息确认ACK机制)
- 网约车司机无证最低罚款拟从10000元降至200元
- 通过JS获取页面表格选中行信息
- 如何使用Aiseesoft Mac FoneTrans传输和管理iOS文件
- 软件测试流程及规范-01
- 华为AR1220路由器配置GRE隧道
- Bochs使用笔记(Bochs虚拟机下安装DOS 6.22)
- 好文分享 行到艰难处 方是修心时
- Android之内存泄漏调试学习与总结,完整PDF
- 通达信交易接口可以设定自动止盈止损吗?
- Tomcat配置通过域名访问