我們現在都知道python的多線程是個坑了,那么多進程在這個時候就變得很必要了。多進程實現了多CPU的利用,效率簡直棒棒噠~~~
擁有一個多進程程序:

1 #!/usr/bin/env python 2 #-*-coding:utf-8-*- 3 __author__ = 'Eva_J' 4 import multiprocessing 5 import time 6 7 def func(msg): 8 for i in range(3): 9 print msg 10 time.sleep(1) 11 12 if __name__ == "__main__": 13 p = multiprocessing.Process(target=func, args=("hello", )) 14 p.start() 15 p.join() 16 print "have done."
按照上面的方法,我們就在自己的代碼中啟動了一個子進程,需要注意的是要想啟動一個子進程,必須加上那句if __name__ == "main",否則就會報錯。 查看了官方文檔說:Safe importing of main module,Make sure that the main module can be safely imported by a new Python interpreter without causing unintended side effects (such a starting a new process).大概就是說,如果我們必須確定當前已經引入了主模塊,來避免一些非預期的副作用。。。總之,加上!就對了!!!
進程池:

1 #!/usr/bin/env python 2 #-*-coding:utf-8-*- 3 __author__ = 'Eva_J' 4 def func(msg): 5 print msg,'*** in func' 6 time.sleep(3) 7 8 if __name__ == "__main__": 9 # 10 pool = multiprocessing.Pool(processes=5) 11 for i in xrange(3): 12 print i 13 pool.apply_async(func, ("hello %d" %(i), )) 14 #pool.apply(func, ("hello %d" %(i), )) 15 pool.close() 16 #pool.terminate() #結束工作進程,不在處理未完成的任務 17 pool.join() #主進程阻塞,等待子進程的退出, join方法要在close或terminate之后使用 18 print "have done."
上圖中的方法就是進程池的使用,這里重點的介紹一些進程池相關的方法。
首先,我們為進程注入func,有兩種方式:apply_async表示異步,就是子進程接收到請求之后就各自去執行了,而apply表示同步,子進程們將一個一個的執行,后一個子進程的執行永遠以前一個子進程的結束為信號,開始執行。還是吃飯的例子。。。異步就是當我通知子進程要去吃飯的時候,他們就同時去吃飯了,同步就是他們必須一個一個的去,前一個沒回來,后一個就不能去。
close方法:說關閉進程池,至此,進程池中不在有進程可以接受任務。
terminate和join是一對方法,表示的內容截然相反,執行terminate是結束當前進程池中的所有進程,不管值沒執行完。join方法是阻塞主進程,等待子進程執行完畢,再繼續執行主進程。需要注意的是:這兩個方法都必須在close方法之后執行。當然我們也可以不執行這兩個方法,那么子進程和主進程就各自執行各自的,無論執行到哪里,子進程會隨着主進程的結束而結束。。。
獲取進程池中進程的執行結果:

1 #!/usr/bin/env python 2 #-*-coding:utf-8-*- 3 __author__ = 'Eva_J' 4 import multiprocessing 5 import time 6 7 def func(msg): 8 print "msg : ", msg 9 time.sleep(3) 10 print "end" 11 return "multi_result : " + msg 12 13 if __name__ == "__main__": 14 pool = multiprocessing.Pool(processes=4) 15 result = [] 16 for i in xrange(3): 17 msg = "hello %d" %(i) 18 multi_result = pool.apply_async(func, (msg, )) 19 result.append(multi_result) 20 pool.close() 21 pool.join() 22 for res in result: 23 print res.get() 24 print "have done."
沒啥好說的,區別在黃框框里,自取不謝~~~
進程之間的內存共享:
我們之前說過,正常情況下,每個進程都擁有自己的內存空間,因此進程間的內存是無法共享的。
但是python卻提供了我們方法,讓我們程序的子進程之間實現簡單的數據共享。
一個是Array數組,一個是multiprocessing模塊中的Manager類。需要注意的是,Array數組的大小必須固定,Manager需要在linux系統下運行。代碼在下面啦!!
1 #!/usr/bin/env python 2 #-*-coding:utf-8-*- 3 __author__ = 'Eva_J' 4 #方法一,Array 5 from multiprocessing import Process,Array 6 temp = Array('i', [11,22,33,44]) 7 8 def Foo(i): 9 temp[i] = 100+i 10 for item in temp: 11 print i,'----->',item 12 13 for i in range(2): 14 p = Process(target=Foo,args=(i,)) 15 p.start()
1 #!/usr/bin/env python 2 #-*-coding:utf-8-*- 3 __author__ = 'Eva_J' 4 #方法二:manage.dict()共享數據 5 from multiprocessing import Process,Manager 6 7 manage = Manager() 8 9 dic = manage.dict() 10 11 def Foo(i): 12 dic[i] = 100+i 13 print dic.values() 14 15 if __name__ == "__main__": 16 for i in range(2): 17 p = Process(target=Foo,args=(i,)) 18 p.start() 19 p.join()
參考文獻:
python進程池:http://www.cnblogs.com/kaituorensheng/p/4465768.html
python多進程的使用示例:http://outofmemory.cn/code-snippet/2267/Python-duojincheng-multiprocessing-usage-example
python的線程、進程和協程:http://www.cnblogs.com/wupeiqi/articles/5040827.html
python的內存共享:http://www.cnblogs.com/dkblog/archive/2011/03/14/1983250.html
python的多進程編程:http://www.cnblogs.com/kaituorensheng/p/4445418.html
