进程池和multiprocess.Pool模块
一、为什么要有进程池
首先,创建进程需要消耗时间,销毁进程也需要时间。其次,即使开启了成千上万的进程,操作系统也不能让它们同时执行,这样反而会影响程序的效率。因此我们不能无限制的根据任务开启或者结束进程。
进程池:定义了一个池子,在里面放上固定数量的进程,有需求来了,就拿这个池中的一个进程来处理任务,等到处理完毕,进程并不关闭,而是将进程再放回进程池中继续等待认为。如果有许多任务需要执行,池中的进程数量不够,任务就要等待之前的进程执行任务完毕归来,拿到空闲进程才能继续执行。
总结:也就是说,池中进程的数量是固定的,那么同一时间最多有固定数量的进程再运行。这样 不会增加操作系统的调度难度,还节省了开闭进程的时间,也一定程度上能够实现并发效果。
二、进程池和多进程效率对比
import os
import time
import random
from multiprocessing import Pool
from multiprocessing import Process
def func(i):
i += 1
if __name__ == '__main__':
p = Pool(5) # 创建了5个进程
start = time.time()
p.map(func,range(1000))
p.close() # 是不允许再向进程池中添加任务
p.join()
print(time.time() - start) # 0.35544490814208984
start = time.time()
l = []
for i in range(1000):
p = Process(target=func,args=(i,)) # 创建了一百个进程
p.start()
l.append(p)
[i.join() for i in l]
print(time.time() - start) # 101.00088691711426
import os,time
from multiprocessing import Pool def work(n):
print('%s run' %os.getpid())
time.sleep(3)
return n**2 if __name__ == '__main__':
p=Pool(3) #进程池中从无到有创建三个进程,以后一直是这三个进程在执行任务
res_l=[]
for i in range(10):
res=p.apply(work,args=(i,)) # 同步调用,直到本次任务执行完毕拿到res,等待任务work执行的过程中可能有阻塞也可能没有阻塞
# 但不管该任务是否存在阻塞,同步调用都会在原地等着
print(res_l)
进程池的同步调用
import os
import time
import random
from multiprocessing import Pool def work(n):
print('%s run' %os.getpid())
time.sleep(random.random())
return n**2 if __name__ == '__main__':
p=Pool(3) #进程池中从无到有创建三个进程,以后一直是这三个进程在执行任务
res_l=[]
for i in range(10):
res=p.apply_async(work,args=(i,)) # 异步运行,根据进程池中有的进程数,每次最多3个子进程在异步执行
# 返回结果之后,将结果放入列表,归还进程,之后再执行新的任务
# 需要注意的是,进程池中的三个进程不会同时开启或者同时结束
# 而是执行完一个就释放一个进程,这个进程就去接收新的任务。
res_l.append(res) # 异步apply_async用法:如果使用异步提交的任务,主进程需要使用jion,等待进程池内任务都处理完,然后可以用get收集结果
# 否则,主进程结束,进程池可能还没来得及执行,也就跟着一起结束了
p.close()
p.join()
for res in res_l:
print(res.get()) #使用get来获取apply_aync的结果,如果是apply,则没有get方法,因为apply是同步执行,立刻获取结果,也根本无需get
进程池的异步调用
通过进程池利用socket实现并发聊天
#Pool内的进程数默认是cpu核数,假设为4(查看方法os.cpu_count())
#开启6个客户端,会发现2个客户端处于等待状态
#在每个进程内查看pid,会发现pid使用为4个,即多个客户端公用4个进程
from socket import *
from multiprocessing import Pool
import os server=socket(AF_INET,SOCK_STREAM)
server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
server.bind(('127.0.0.1',8080))
server.listen(5) def talk(conn):
print('进程pid: %s' %os.getpid())
while True:
try:
msg=conn.recv(1024)
if not msg:break
conn.send(msg.upper())
except Exception:
break if __name__ == '__main__':
p=Pool(4)
while True:
conn,*_=server.accept()
p.apply_async(talk,args=(conn,))
# p.apply(talk,args=(conn,client_addr)) #同步的话,则同一时间只有一个客户端能访问
server端
from socket import *
client=socket(AF_INET,SOCK_STREAM)
client.connect(('127.0.0.1',8080))
while True:
msg=input('>>: ').strip()
if not msg:continue
client.send(msg.encode('utf-8'))
msg=client.recv(1024)
print(msg.decode('utf-8'))
client端
import os
import time
from multiprocessing import Pool
# 参数 概念 回调函数
def func(i): # 多进程中的io多,
print('子进程%s:%s'%(i,os.getpid()))
return i*'*' def call(arg): # 回调函数是在主进程中完成的,不能传参数,只能接受多进程中函数的返回值
print('回调 :',os.getpid())
print(arg) if __name__ == '__main__':
print('---->',os.getpid())
p = Pool(5)
for i in range(10):
p.apply_async(func,args=(i,),callback=call)
p.close()
p.join()
回调函数
如果在主进程中等待进程池中所有任务都执行完毕后,再统一处理结果,则无需回调函数。
from multiprocessing import Pool
import time,random,os def work(n):
time.sleep(1)
return n**2
if __name__ == '__main__':
p=Pool() res_l=[]
for i in range(10):
res=p.apply_async(work,args=(i,))
res_l.append(res) p.close()
p.join() #等待进程池中所有进程执行完毕 nums=[]
for res in res_l:
nums.append(res.get()) #拿到所有结果
print(nums) #主进程拿到所有的处理结果,可以在主进程中进行统一进行处理
无需回调函数
进程池和multiprocess.Pool模块的更多相关文章
- 进程同步控制(锁,信号量,事件), 进程通讯(队列和管道,生产者消费者模型) 数据共享(进程池和mutiprocess.Pool模块)
参考博客 https://www.cnblogs.com/xiao987334176/p/9025072.html#autoid-1-1-0 进程同步(multiprocess.Lock.Semaph ...
- 进程池 和 multiprocessing.Pool模块
进程池的概念 在程序实际处理问题过程中,忙时会有成千上万的任务需要被执行,闲时可能只有零星任务.那么在成千上万个任务需要被执行的时候,我们就需要去创建成千上万个进程么?首先,创建进程需要消耗时间,销毁 ...
- Python之进程 3 - 进程池和multiprocess.Poll
一.为什么要有进程池? 在程序实际处理问题过程中,忙时会有成千上万的任务需要被执行,闲时可能只有零星任务.那么在成千上万个任务需要被执行的时候,我们就需要去创建成千上万个进程么?首先,创建进程需要消耗 ...
- python 进程池(multiprocessing.Pool)和线程池(threadpool.ThreadPool)的区别与实例
一般我们是通过动态创建子进程(或子线程)来实现并发服务器的,但是会存在这样一些缺点: 1.动态创建进程(或线程)比较耗费时间,这将导致较慢的服务器响应. 2.动态创建的子进程通常只用来为一个客户服务 ...
- python全栈开发 * 进程池,线程理论 ,threading模块 * 180727
一.进程池 (同步 异步 返回值) 缺点: 开启进程慢 几个CPU就能同时运行几个程序 进程的个数不是无线开启的 应用: 100个任务 进程池 如果必须用多个进程 且是高计算型 没有IO型的程序 希望 ...
- python进程池:multiprocessing.pool
本文转至http://www.cnblogs.com/kaituorensheng/p/4465768.html,在其基础上进行了一些小小改动. 在利用Python进行系统管理的时候,特别是同时操作多 ...
- python multiprocess pool模块报错pickling error
问题 之前在调用class内的函数用multiprocessing模块的pool函数进行多线程处理的时候报了以下下错误信息: PicklingError: Can't pickle <type ...
- 进程池的同步方法 pool.apply
from multiprocessing import Pool,Process def f1(n): print(n) return n*n if __name__ == "__main_ ...
- python 全栈开发,Day40(进程间通信(队列和管道),进程间的数据共享Manager,进程池Pool)
昨日内容回顾 进程 multiprocess Process —— 进程 在python中创建一个进程的模块 start daemon 守护进程 join 等待子进程执行结束 锁 Lock acqui ...
随机推荐
- Web学习之CSS总结
银角大王武Sir的博客地址 1.positoin属性固定元素的定位类型 说明:这个属性定义建立元素布局所用的定位机制.任何元素都可以定位,不过绝对或固定元素会生成一个块级框,而无论该元素是什么类型.相 ...
- MiniUI学习笔记1-表单控件
1.输入框样式 class="mini-textbox" //普通输入框 class="mini-password" //密码输入框 class="m ...
- VPS 安装MySQL
目前Centos下默认支持的数据库是MariaDB,MariaDB是mysql的增强版本,由于mysql被Oracle收购之后,mysql之父担心之后mysql会变成闭源的软件,就又开发了这个版本,支 ...
- 2018-10-16-weekly
Algorithm 判断子序列 What 给定字符串 s 和 t ,判断 s 是否为 t 的子序列.如,"ace"是"abcde"的一个子序列,而"a ...
- [python 学习] sys模块
sys.stdout sys.stdin
- 理解Promise (4)
then 方法必须 返回一个新的promise promise2 = promise1.then(onFulfilled, onRejected); 新的Promise 必须返回传递两个方法 onF ...
- [BZOJ] 书堆
问题描述 蚂蚁是勤劳的动物,他们喜欢挑战极限?现在他们迎来了一个难题!蚂蚁居住在图书馆里,图书馆里有大量的书籍.书是形状大小质量都一样的矩形.蚂蚁要把这些书摆在水平桌子的边緣.蚂蚁喜欢整洁的布置,所以 ...
- iOS----实现scrollView或者scrollView的子类下拉图片放大的效果
代码是通过Tableview来说明的,用在其他情况下同样适用 - (void)viewDidLoad { [super viewDidLoad]; _imageview = [[UIImageView ...
- 未能加载文件或程序集 ICSharpCode.SharpZipLib
Ui调用Webservice ,Webservice调用Bl BL中明明有那个dll文件 后来发现是webservice里面没有 在附加调试的时候,断点在bl层中
- c# 生成文件目录树
class Program { //遍历目录名含有M00到M11的目录 //生成文件目录树(去除文件名中含有scc\Designer\designer\resx的文件) //生成的文件保存在D:\\a ...