进程池_Pool

当需要创建子进程数量不多的时候,可以直接利用multiprocessing中的Process动态生成多个进程
但是如果是成百甚至上千个任务,手动地创建它的工作量很大,此时就可以利用到multiprocessing下的pool
初始化Pool时,可以指定一个最大的进程数,当有新的请求提交到Pool中时,
如果池子还没有满,那么就会创建一个新的进程来执行该请求,但如果满了(池子中的进程已经到达最大数量)
那么该请求就会等待,直到池中有进程结束,才会创建新的进程来执行。
 
 1 from multiprocessing import Pool
 2 import os,time,random
 3 
 4 #定义一个函数
 5 def download(i):
 6     print("(%d)--进程ID为%d的进程开始执行"%(i,os.getpid()))
 7     t_start = time.time()
 8 
 9     time.sleep(2* random.random())
10     t_stop = time.time()
11     print("(%d)--进程ID为%d的进程执行完毕,耗时%f秒"%(i,os.getpid(),t_stop-t_start))
12 
13 
14 
15 if __name__ == '__main__':
16     po = Pool(3) #定义一个进程池,最大进程数量
17     for i in range(10):
18         #同步(自加阻塞)
19         po.apply(func=download,args=(i,)) #同步
20 
21 
22         # 每次循环将会用空闲出来的子进程去调用目标--异步
23         # po.apply_async(func=download,args=(i,)) #异步
24 
25     print('-------start---------')
26 
27     po.close() #关闭进程池,关闭后po就不再接受新的请求
28     po.join() #等待进程池中所有子进程执行完成,阻塞必须放在close之后
29     print('-------end---------')
-------start---------
(0)--进程ID为6476的进程开始执行
(1)--进程ID为6212的进程开始执行
(2)--进程ID为6284的进程开始执行
(0)--进程ID为6476的进程执行完毕,耗时0.975056秒
(3)--进程ID为6476的进程开始执行
(1)--进程ID为6212的进程执行完毕,耗时1.030059秒
(4)--进程ID为6212的进程开始执行
(2)--进程ID为6284的进程执行完毕,耗时1.735099秒
(5)--进程ID为6284的进程开始执行
(4)--进程ID为6212的进程执行完毕,耗时1.078062秒
(6)--进程ID为6212的进程开始执行
(6)--进程ID为6212的进程执行完毕,耗时0.373021秒
(7)--进程ID为6212的进程开始执行
(3)--进程ID为6476的进程执行完毕,耗时1.759101秒
(8)--进程ID为6476的进程开始执行
(5)--进程ID为6284的进程执行完毕,耗时1.608092秒
(9)--进程ID为6284的进程开始执行
(9)--进程ID为6284的进程执行完毕,耗时0.325019秒
(7)--进程ID为6212的进程执行完毕,耗时1.248071秒
(8)--进程ID为6476的进程执行完毕,耗时1.817104秒
-------end---------
* 刚开始有3个进程,执行完一个之后,后面的新进程添加进来,依次类推。谁先运行完,不一定。
* 这里`po.join()`阻塞程序执行,主进程和子进程都用print。如果没有,会看不到效果。
 
 1 from multiprocessing import Pool
 2 import os,time,random
 3 
 4 #定义一个函数
 5 def download(i):
 6     print("(%d)--进程ID为%d的进程开始执行"%(i,os.getpid()))
 7     t_start = time.time()
 8 
 9     time.sleep(2* random.random())
10     t_stop = time.time()
11     print("(%d)--进程ID为%d的进程执行完毕,耗时%f秒"%(i,os.getpid(),t_stop-t_start))
12 
13 
14 
15 if __name__ == '__main__':
16     po = Pool(3) #定义一个进程池,最大进程数量
17     for i in range(10):
18         #同步(自加阻塞)
19         # po.apply(func=download,args=(i,)) #同步
20 
21 
22         # 每次循环将会用空闲出来的子进程去调用目标--异步
23         po.apply_async(func=download,args=(i,)) #异步
24 
25     print('-------start---------')
26 
27     po.close() #关闭进程池,关闭后po就不再接受新的请求
28     po.join() #等待进程池中所有子进程执行完成,阻塞必须放在close之后
29     print('-------end---------')
#同步时,输出的结果:
(0)--进程ID为5648的进程开始执行
(0)--进程ID为5648的进程执行完毕,耗时0.069004秒
(1)--进程ID为2556的进程开始执行
(1)--进程ID为2556的进程执行完毕,耗时1.278073秒
(2)--进程ID为1864的进程开始执行
(2)--进程ID为1864的进程执行完毕,耗时1.308075秒
(3)--进程ID为5648的进程开始执行
(3)--进程ID为5648的进程执行完毕,耗时1.673096秒
(4)--进程ID为2556的进程开始执行
(4)--进程ID为2556的进程执行完毕,耗时0.887051秒
(5)--进程ID为1864的进程开始执行
(5)--进程ID为1864的进程执行完毕,耗时1.699097秒
(6)--进程ID为5648的进程开始执行
(6)--进程ID为5648的进程执行完毕,耗时1.817104秒
(7)--进程ID为2556的进程开始执行
(7)--进程ID为2556的进程执行完毕,耗时0.595034秒
(8)--进程ID为1864的进程开始执行
(8)--进程ID为1864的进程执行完毕,耗时0.231013秒
(9)--进程ID为5648的进程开始执行
(9)--进程ID为5648的进程执行完毕,耗时1.656095秒
-------start---------
-------end---------

 

 

同步和异步的区别:

 

 

 

 

 

 

 
posted @ 2018-07-10 14:23  doitjust  阅读(163)  评论(0编辑  收藏  举报