python的多進程和多線程
thread、threading、process、multiprocessing 等等模塊網上資料很多,不贅述了
這裏主要簡要說明一下自己平時能用到的進程池、線程池,使用”池“的好處是不需要自己去實現各種LOCK.
- from multiprocessing.dummy import Pool 就可以使用多線程
- from multiprocessing import Poo 可以使用多進程
- python的多線程並不是網上說的那樣,要看官方文檔!不要人云亦云,python的GIL(Global Interpreter Lock)是cpython解釋器的問題,和語言無關,任何一個CPython線程如果要執行,就必須先獲取這個GIL。後果就是在CPython中,幾乎是沒有線程並行的,不論你開多少個線程,同一時刻只有獲取GIL的那個線程能夠執行。爲什麼要說幾乎呢,這是因爲提供給python的C庫中,還是有解決方案的。解決方案是sleep的代碼,在執行sleep之前,通過一個宏來釋放GIL,然後在睡眠結束執行其他代碼前又獲取GIL。這樣可以在很大程度上避開GIL來取得線程並行的效果。只要不是整個過程都在瘋狂使用CPU,那麼多線程的運行效率要超過多進程(進程的創建需要OS分配資源,建立PCB等等,開銷要比線程大的多)
- python 的其他兩個分支,Jython和IronPython,卻都沒有GIL的問題,從而可以實現真正的線程並行(注意並行和併發的區別,別理解錯了)
p=Pool(3) #啓動3個進程或者線程
p=Pool() #根據你的CPU核數設置默認值。比如電腦8核,p=Pool()和p=Pool(8)是等效的
#coding=utf-8
import time
#如果想變成多進程,把下面的dummy去掉就好
from multiprocessing.dummy import Pool
class person:
def setName(self,name):
self.name=name
def getName(self):
print(self.name)
def greet(self):
time.sleep(1)
print("hello ,i am %s"%self.name)
def examp(name):
perso=person()
perso.setName(name)
perso.greet()
if __name__ == '__main__':
aa=time.time()
people=['tom','amy','mkie','tony','yang','jouge','bob','jany']
#Pool默認啓動的進程/線程數量是cpu的核數(準確的說是邏輯運算核心數量)
p=Pool()
for i in people:
p.apply_async(examp, args=(i,))
p.close()
p.join()
bb=time.time()
print(bb-aa)