multiprocessing是python的多进程管理包,和threading.Thread类似。直接从侧面用subprocesses替换线程使用GIL的方式,由于这一点,multiprocessing模块可以让程序员在给定的机器上充分的利用CPU。
在multiprocessing中,通过创建Process对象生成进程,然后调用它的start()方法
1 from multiprocessing import Process 2 3 def f(name): 4 print('hello', name) 5 6 if __name__ == '__main__': 7 p = Process(target=f, args=('bob',)) 8 p.start() 9 p.join()
和线程的方法都差不多
daemon:
daemon = True 不等待子线程完事就返回
join:
join(timeout=3) 等待线程3秒,超时后继续执行代码
1 #-*- coding:utf-8 -*- 2 from multiprocessing import Process 3 import time 4 def f(name): 5 time.sleep(2) 6 print('hello', name) 7 8 if __name__ == '__main__': 9 p = Process(target=f, args=('p',)) 10 #默认Flase 等待子线程执行完毕,TRUE 不等待子线程完事 11 #p.daemon = True 12 p.start() 13 p1 = Process(target=f, args=('p1',)) 14 p1.start() 15 16 #等待3秒超时,超时过后才能继续执行 17 p1.join(timeout=3) 18 19 print("end")
进程间的数据操作
1 #-*- coding:utf-8 -*- 2 from multiprocessing import Process 3 import time 4 5 li = [] 6 7 def foo(i): 8 li.append(i) 9 #查看进程中的li列表 10 print("li:",li) 11 12 13 14 if __name__ == '__main__' : 15 for i in range(10): 16 p = Process(target=foo,args=(i,)) 17 p.start() 18 '''结果: 19 ('li:', [1]) 20 ('li:', [3]) 21 ('li:', [0]) 22 ('li:', [4]) 23 ('li:', [6]) 24 ('li:', [2]) 25 ('li:', [5]) 26 ('li:', [9]) 27 ('li:', [7]) 28 ('li:', [8]) 29 '''
进程间默认是无法通信的,如果向通信就通信 安全就完全无法保证
进程池
进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。
进程池中有两个方法:
- apply
- apply_async
1 # -*- coding:utf-8 -*- 2 from multiprocessing import Process,Pool 3 import time 4 5 def Foo(i): 6 time.sleep(1) 7 print("Foo:%d"%i) 8 return i+100 9 10 #Foo最后return 的值会传递到Bar的参数中。 11 def Bar(arg): 12 print("callback:%d"%arg) 13 14 15 16 if __name__ == '__main__': 17 pool = Pool(5) 18 for i in range(10): 19 #同步执行了每个进程都会join,也就是说串行执行等一个进程完毕后在执行下一个 20 #pool.apply(Foo,(i,)) 21 22 #异步执行,callback可选,执行完子进程后将return结果带入到回调函数中。 23 pool.apply_async(func=Foo, args=(i,),callback=Bar) 24 25 #get方法获取异步执行函数的return结果 26 #print pool.apply_async(func =Foo, args=(i,)).get() 27 28 pool.close() 29 #这个是对进程池操作,等待所有子进程完毕在关闭,如果注释主程序将不会等完子进程完事在退出,而是直接退出 30 #执行这个方法之前必须执行pool.close()或 pool.terminate()关闭池 31 pool.join()
pool下的join源码:
1 def join(self): 2 debug('joining pool') 3 #状态是CLOSE或TERMINATE 4 assert self._state in (CLOSE, TERMINATE) 5 self._worker_handler.join() 6 self._task_handler.join() 7 self._result_handler.join() 8 for p in self._pool: 9 p.join()