进程池
- 当我们创建的子进程数量不多时,可以直接利用multiprocessing中的Process动态生成,但是同时创建成百上千,需要用到multiprocessing中Pool方法
- 初始还Pool可以指定一个最大进程数,当有新的请求到达Pool时,如果池还没有满,就会创建一个新的进程,如果已经达到最大值,就会等待,直到进程池的进程执行结束,才会执行等待的进程
Pool常用方法:
-apply_async(func ,args,kwds) : 使用非阻塞的方法调用func(并行执行,堵塞方式等待上个进程退出才能执行下一个进程),args为func的参数列表,args为func的关键字参数列表
- close() : 关闭pool,使其不再接收新的任务
- join () : 主线程阻塞,等待子进程退出,必须在close之后
举例:
'''
1,进程池的基本操作
'''
from multiprocessing import Pool
import time,os
def work1():
for i in range(10):
print('work1-------{}---{}'.format(i,os.getpid()))
time.sleep(0.1)
def work2():
for i in range(10):
print('work2-------{}---{}'.format(i,os.getpid()))
time.sleep(0.1)
def main():
po = Pool(5) #创建一个进程池,池中有5个进程
for i in range(10): #依次从进程池中拿出进程,创建10个进程,实际每次最多获取5个,其他等待
po.apply_async(work1)
for i in range(10): #依次从进程池中拿出进程,创建10个进程,实际每次最多获取5个,其他等待
po.apply_async(work2)
po.close() #关闭进程池,进程池不在接收新的任务
po.join() #等待主进程执行
if __name__ == '__main__':
main()
进程池之间的通讯
进程池也不能使用queue,进程池有自己的队列Manager
'''
1,进程池的基本操作\
2,进程池的通讯,队列
'''
from multiprocessing import Pool,Manager
import time,os
def work1(q):
for i in range(10):
print('work1-------{}---{}'.format(i,os.getpid()))
q.put(1)
time.sleep(0.1)
def work2(q):
for i in range(10):
print('work2-------{}---{}'.format(i,os.getpid()))
time.sleep(0.1)
print('获取队列的值',q.get())
def main():
q1 =Manager().Queue()
po = Pool(5) #创建一个进程池,池中有5个进程
for i in range(10): #依次从进程池中拿出进程,创建10个进程,实际每次最多获取5个,其他等待
po.apply_async(work1,(q1,))
for i in range(10): #依次从进程池中拿出进程,创建10个进程,实际每次最多获取5个,其他等待
po.apply_async(work2,(q1,))
po.close() #关闭进程池,进程池不在接收新的任务
po.join() #等待主进程执行
if __name__ == '__main__':
main()
进程,线程,协程的比较
1,进程是资源分配的单位
2,线程是操作系统调度的单位
3,线程切换需要的资源很大,效率很低
4,线程切换需要资源一般,效率一般
5,协程切换任务的资源最小,效率高
6,多进程,多线程根据cpu的核数可能是并行,但是协程是在一个线程中,所以是并发
7,python中的线程由于GIL锁,不能实现并行操作
常见问题
1,
进程池已经关闭不在接收新的任务
网友评论