Part 4系统编程之进程---进程池

(一)简介

为什么要有进程池?进程池的概念。

在程序实际处理问题过程中,忙时会有成千上万的任务需要被执行,闲时可能只有零星任务。那么在成千上万个任务需要被执行的时候,我们就需要去创建成千上万个进程么?首先,创建进程需要消耗时间,销毁进程也需要消耗时间。第二即便开启了成千上万的进程,操作系统也不能让他们同时执行,这样反而会影响程序的效率。因此我们不能无限制的根据任务开启或者结束进程。那么我们要怎么做呢?

在这里,要给大家介绍一个进程池的概念,定义一个池子,在里面放上固定数量的进程,有需求来了,就拿一个池中的进程来处理任务,等到处理完毕,进程并不关闭,而是将进程再放回进程池中继续等待任务。如果有很多任务需要执行,池中的进程数量不够,任务就要等待之前的进程执行任务完毕归来,拿到空闲进程才能继续执行。也就是说,池中进程的数量是固定的,那么同一时间最多有固定数量的进程在运行。这样不会增加操作系统的调度难度,还节省了开闭进程的时间,也一定程度上能够实现并发效果。

(二)语法格式

我们通过下面的一个简单实例来了解创建进程池的基本方法:

 1 import time
 2 from multiprocessing import Pool
 3 def fc(i):
 4     time.sleep(0.5)
 5     print('func%s'%i)
 6  
 7 if __name__ == '__main__':
 8     p = Pool(5)
 9     for i in range(5):
10         
11         p.apply(func=fc,args=(i,))  # 同步调用
12         或者
13         p.apply_async(func=fc, args=(1,))  # 异步调用    

(三)同步调用和异步调用的区别:

通过上面的语法格式,我们可以看出,存在同步和异步调用:

 

同步调用:直到本次任务执行完毕时,才加入下一个任务,等待本次任务执行的过程中可能有阻塞也可能没有阻塞,但不管该任务是否存在阻塞,同步调用都会在原地等着。

看如下例子:

 1 from multiprocessing import Pool
 2 import random
 3 import os
 4 import time
 5 
 6 
 7 def f(i):
 8     time_start = time.time()
 9     print("---进程%d运行中,pid=%d---"% (i, os.getpid()))
10     time.sleep(random.randint(1,4))
11     time_stop = time.time()
12     print('进程%d耗时%0.5f'% (i, (time_stop-time_start)))
13 
14 
15 if __name__ == '__main__':
16     po = Pool(3)
17     for i in range(10):
18         po.apply(func=f, args=(i,))
19 
20     print("----start----")
21     print('----stop----')
22 
23 》》》输出:
24 ---进程0运行中,pid=10244---
25 进程0耗时3.00086
26 ---进程1运行中,pid=8140---
27 进程1耗时2.00089
28 ---进程2运行中,pid=27480---
29 进程2耗时3.00057
30 ---进程3运行中,pid=10244---
31 进程3耗时2.00040
32 ---进程4运行中,pid=8140---
33 进程4耗时1.00129
34 ---进程5运行中,pid=27480---
35 进程5耗时1.00084
36 ---进程6运行中,pid=10244---
37 进程6耗时2.00106
38 ---进程7运行中,pid=8140---
39 进程7耗时2.00045
40 ---进程8运行中,pid=27480---
41 进程8耗时3.00015
42 ---进程9运行中,pid=10244---
43 进程9耗时3.00059
44 ----start----
45 ----stop----

可以看到,如果任务有返回值,那么会一个一个的返回。

 

异步调用:根据进程池中有的进程数,每次最多三个子进程在异步执行每次执行完一个就释放一个进程,这个进程就去接收新的任务。所以如果使用异步提交任务,主进程需要使用join,等待进程池内的任务处理完,否则,主进程结束,进程池可能还没有来得及执行,就跟着一起结束了。

看如下实例:

 1 from multiprocessing import Pool
 2 import random
 3 import os
 4 import time
 5 
 6 
 7 def f(i):
 8     time_start = time.time()
 9     print("---进程%d运行中,pid=%d---"% (i, os.getpid()))
10     time.sleep(random.randint(1,4))
11     time_stop = time.time()
12     print('进程%d耗时%0.5f'% (i, (time_stop-time_start)))
13 
14 
15 if __name__ == '__main__':
16     po = Pool(3)
17     for i in range(10):
18         po.apply_async(func=f, args=(i,))
19 
20     print("----start----")
21     po.close()
22     po.join()
23     print('----stop----')
24 
25 
26 》》》输出:
27 ----start----
28 ---进程0运行中,pid=9608---
29 ---进程1运行中,pid=4644---
30 ---进程2运行中,pid=19992---
31 进程1耗时1.00100
32 ---进程3运行中,pid=4644---
33 进程3耗时1.00022
34 ---进程4运行中,pid=4644---
35 进程0耗时3.00073
36 ---进程5运行中,pid=9608---
37 进程2耗时3.00091
38 ---进程6运行中,pid=19992---
39 进程5耗时2.00013
40 ---进程7运行中,pid=9608---
41 进程4耗时3.00048
42 ---进程8运行中,pid=4644---
43 进程7耗时1.00039
44 ---进程9运行中,pid=9608---
45 进程8耗时1.00056
46 进程6耗时4.00056
47 进程9耗时3.00023
48 ----stop----

 

转载于:https://www.cnblogs.com/boru-computer/p/9741728.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值