进程池
启动太多个进程,会使系统运行快速变慢,因为相当于克隆了父进程数据,使内存资源开销变大,容易将系统搞瘫。(多线程开销很下,只是使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