进程池原理及效率测试Pool

为什么会有进程池的概念?

当我们开启50个进程让他们都将100这个数减1次减到50,你会发现特别慢!

效率问题,原因:

1,开辟内存空间。因为每开启一个进程,都会开启一个属于这个进程池的内存空间,因为进程与进程之间数据是完全隔离的。

2,并且这些独立的内存空间会有许多寄存器,堆栈,文件等,他们存着这个进程里面的变量和数据等。所以生成这些东西都会耗时。

3,生成这么多进程,都需要系统调度,这个也会耗时。不仅这样,还会涉及到进程使用cpu的时候,当a进程使用一段时间cpu,b进程要去使用cpu,za和b中间的节点不仅要记录a进程执行到这,还要调用b进程之前执行的结果,所以在这个节点不仅涉及到cpu的切换,还涉及到寄存器,堆栈等包含的数据,还有内存空间的切换。

所以,我们不会无休止的去开启进程,而是设计一个池子,这个池子就是进程池。

进程池的含义?

python中的进程池,在你还没有创建进程之前,先创建一个属于进程的池子。这个池子指定能存放多少个进程,比如说5个进程,因此会先创建这5个进程。当任务进来的时候,比如说50个任务需要50个进程去处理,但是不会生成50个进程,而是排队去进程池里面拿进程处理任务,所以同一时刻最多有5个进程在处理任务,当任务处理完毕,不会将进程销毁,而是放回到进程池,在让其他任务进来让这些进程处理。

所以,进程池的优点有:

1,提高效率,节省开辟进程和开辟内存空间的时间及销毁进程的时间。

2,节省内存空间。

更高级的进程池

这种进程池不给设置固定数量的进程,而是有一个范围,比如最少3个进程,最多30个进程。当任务或用户量增加时,进程池里面的进程数量会加加加,一直加到最大值,当任务或用户量减少,造成很多进程长时间没用,就会减减减,直到减到最小值。这样做的好处会系统回收用不到的进程,会给操作系统减负。

但是python里面只有第一种进程池,他不会将进程池进行收缩。

怎么使用?如下代码:

from multiprocessing import Pool


def func(n):
    for i in range(3):
        print(n +1)  # 将传入的值打印三次,1到10每个值打印三次


if __name__ == "__main__":
    pool = Pool(5)  # 创建了一个包含5个进程的进程池
    pool.map(func, range(10))  # 这样用map就起进程了,另外range(10)这个位置传的值一定要是可迭代的,map只能传可迭代的。10个任务
# map是异步的,并且不需要close()和join(),并且把每一个返回值放到一个列表中,直接显示出来。

进程池的效率测试:

from multiprocessing import Pool
import time


def func(n):
    for i in range(10):  # 将1到100,每个数打印十次
        print(n +1)


if __name__ == "__main__":
    start = time.time()
    pool = Pool(5)
    pool.map(func, range(100))  # 一百个任务
    t2 = (time.time() - start)
    print(t2)  # 打印花费时间,时间是0.26130008697509766

然后看起100个进程去处理相同数量的任务:

from multiprocessing import Process
import time


def func(n):
    for i in range(10):  # 同样将1到100,每个数打印十次
        print(n+1)


if __name__ == "__main__":
    t1 = time.time()
    p_list = []
    for i in range(100):
        p = Process(target=func, args=(i,))
        p_list.append(p)
        p.start()
    for p in p_list:
        p.join()
    t2 = (time.time() - t1)
    print(t2)  # 3.882610321044922

对比时间差别太大了,进程池的5个进程却比创建100个进程做同样的事儿快的太多了。

合并到同一个代码里面再看效果:

from multiprocessing import Process, Pool
import time

def func(n): for i in range(10): print(n + 1) if __name__ == "__main__": t1 = time.time() pool = Pool(5) pool.map(func, range(100)) t2 = time.time() - t1 t3 = time.time() p_list = [] for i in range(100): p = Process(target=func, args=(i,)) p_list.append(p) p.start() for p in p_list: p.join() t4 = time.time() - t3 print(t2, t4)

打印结果:

0.2582840919494629 4.1498963832855225

所以,进程池的效率比开多个进程效率高得多。

 

posted @ 2018-10-16 21:42  aaronthon  阅读(1608)  评论(0编辑  收藏  举报