进程池

启动太多个进程,会使系统运行快速变慢,因为相当于克隆了父进程数据,使内存资源开销变大,容易将系统搞瘫。(多线程开销很下,只是使cpu的切换过于频繁,导致系统变慢)

进程池(同一时间有多少进程在CPU上运行)  

进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。

进程池中有两个方法:

  • apply  串行,也叫同步执行
  • apply_async  并行,也叫异步执行
#适合linux开启的进程池,在windows上需要导入freeze_support
from  multiprocessing import Process, Pool#Pool游泳池的意思
import time,os

def Foo(i):
    time.sleep(2)
    print('in process',os.getpid())
    return i + 100

def Bar(arg):
    print('-->exec done:', arg)

pool = Pool(5)

for i in range(10):
    pool.apply_async(func=Foo, args=(i,), callback=Bar)#并行
    # pool.apply(func=Foo, args=(i,))#串行

print('end')
pool.close()#记得要把pool关闭掉
#注意先close,再join
pool.join()  # 进程池中所有进程执行完毕后再关闭,如果注释,那么程序直接关闭。

  

#适合windows开启的进程池,在linux上不需要导入freeze_support
from  multiprocessing import Process, Pool,freeze_support
import time,os

def Foo(i):
    time.sleep(2)
    print('in process',os.getpid())
    return i + 100

def Bar(arg):
    print('-->exec done:', arg,' 子进程pid:',os.getpid())

if __name__ == '__main__':#在windows上启动线程池,必须加本句。
#一般程序中本句的作用是为了区分是主动执行这个脚本,还是从别的地方把它当做一个模块去调用。
#如果主动执行这个脚本,下面的代码就执行。如果别人从别的代码里导入本篇程序,就不执行本句内的程序。
#所以本句内的内容只能手动执行这个脚本,用于测试之类。
# 如果不手动执行,被别的地方(本篇程序之外)的程序调用(直接import本篇程序名),就不会执行本句内内容。

    pool = Pool(5)#允许进程池同时放入5个进程,真正调用CPU被允许运行的只有放在进程池里的5个进程。
    # pool = Pool(processes=5)#同上句
    print('主进程的pid:',os.getpid())
    for i in range(10):#启动了10个进程,但是进程池只允许5个运行,其余5个被挂起,但也启动了。
        # pool.apply_async(func=Foo, args=(i,))#并行的结果是5个5个的执行
        # pool.apply(func=Foo, args=(i,))#串行的运行结果是一个一个执行
        pool.apply_async(func=Foo, args=(i,), callback=Bar)#callback:回调,func执行完了就执行callback
        # 注:回调是主进程执行的,不用在子进程中,这样会提高效率,因为主进程pid和子进程pid是相同的。
    print('end')#如果没有join,结果只有本句
    pool.close()#记得要把pool关闭掉
    #注意先close,再join
    pool.join()  # 进程池中所有进程执行完毕后再关闭,如果注释,那么程序直接关闭。

  结果:

主进程的pid: 6216
end
in process 6716
-->exec done: 100  子进程pid: 6216
in process 3316
-->exec done: 101  子进程pid: 6216
in process 6304
-->exec done: 102  子进程pid: 6216
in process 6332
-->exec done: 103  子进程pid: 6216
in process 6824
-->exec done: 104  子进程pid: 6216
in process 6716
-->exec done: 105  子进程pid: 6216
in process 3316
-->exec done: 106  子进程pid: 6216
in process 6304
-->exec done: 107  子进程pid: 6216
in process 6332
-->exec done: 108  子进程pid: 6216
in process 6824
-->exec done: 109  子进程pid: 6216
View Code
原文地址:https://www.cnblogs.com/tianqizhi/p/9442076.html