继续上一篇博客的内容
Python——多进程与多线程的应用
使用类的方式创建新的进程
上篇博客中我们提到了使用Process这个包来创建进程,除此之外,我们还可以自定义一个类,继承Process类,通过实例化这个类来实例化一个新的进程对象,下面请看一个简单的例子
import time
from multiprocessing import Process
class Lakers_Champion(Process):
n = 3
while n > 0:
print("湖人总冠军")
time.sleep(1)
n -= 1
if __name__ == '__main__':
p = Lakers_Champion()
p.start()
p.join()
来看一下运行结果
湖人总冠军
湖人总冠军
湖人总冠军
湖人总冠军
湖人总冠军
湖人总冠军
进程池
当我们项目中需要的子进程数量不多时,可以使用Process来创建进程或通过继承Process来实例化一个进程,但是当我们需要成百上千的进程时,再通过这种方法创建进程显然是低效的,这个时候我们就需要引入新的概念——进程池,在Python中可以用到multiprocessing模块提供的Pool。
from multiprocessing import Pool
初始化Pool时, 可以指定⼀个最⼤进程数, 当有新的请求提交到Pool中时,如果池还没有满, 那么就会创建⼀个新的进程⽤来执⾏该请求; 但如果池中的进程数已经达到指定的最⼤值, 那么该请求就会等待, 直到池中有进程结束, 才会创建新的进程来执⾏,我们通过一个简单的例子来了解相关的使用方法
from multiprocessing import Process, Pool
import random
import time
def work(num):
print(random.random()*num)
time.sleep(3)
if __name__ == '__main__':
po = Pool() # 定义一个进程池,最大进程数为3,默认大小为CPU核数
for i in range(10):
po.apply_async(work, (i,)) # apply_async选择要调用的目标,每次循环会用空出来的子进程去调用目标
po.close() # 进程池关闭后不再接收新的请求,指的是不再接收新的请求,并不会杀死正在运行的进程
po.join() # 等待po中所有的子进程结束,必须放在close后面
来看一下运行结果
0.0
0.34984100078459757
0.5201072456606135
0.40449373225754937
1.224435745451367
3.506216623423578
1.4749908838684131
2.6109286282731015
0.6106200958130108
1.4684032840327501
来看一下常用函数的解析
po = Pool()
po.apply_async(func[, args[, kwds]]) # 使⽤⾮阻塞⽅式调⽤func(并⾏执⾏, 堵塞⽅式必须等待上⼀个进程退出才能执⾏下⼀个进程) , args为传递给func的参数列表, kwds为传递给func的关键字参数列表;
po.apply(func[, args[, kwds]]) # (了解即可几乎不用) 使⽤阻塞⽅式调⽤func
po.close() # 关闭Pool, 使其不再接受新的任务;
po.terminate() # 不管任务是否完成, ⽴即终⽌;
po.join() # 主进程阻塞, 等待⼦进程的退出, 必须在close或terminate之后使⽤;