咱們大多數的時候使用多線程,以及多進程,可是python中因爲GIL全局解釋器鎖的緣由,python的多線程並無真的實現python
實際上,python在執行多線程的時候,是經過GIL鎖,進行上下文切換線程執行,每次真實只有一個線程在運行。因此上邊才說,沒有真的實現多現程。多線程
那麼python的多線程就沒有什麼用了嗎?app
不是這個樣子的,python多線程通常用於IO密集型的程序,那麼什麼叫作IO密集型呢,舉個例子,好比說帶有阻塞的。當前線程阻塞等待其它線程執行。socket
即然說到適合python多線程的,那麼什麼樣的不適合用python多線程呢?url
答案是CPU密集型的,那麼什麼樣的是CPU密集型的呢?百度一下你就知道。spa
如今有這樣一項任務:須要從200W個url中獲取數據?線程
那麼咱們真心不能用多線程,上下文切換是須要時間的,數據量太大,沒法接受。這裏咱們就要用到多進程+協程code
那麼什麼是協程呢?協程
協程,又稱微線程,纖程。英文名Coroutine。blog
協程的概念很早就提出來了,但直到最近幾年纔在某些語言(如Lua)中獲得普遍應用。
協程有什麼好處呢,協程只在單線程中執行,不須要cpu進行上下文切換,協程自動完成子程序切換。
這裏沒有使用yield協程,這個python自帶的並非很完善,至於爲何有待於你去研究了。
這裏使用比較完善的第三方協程包gevent
pip install gevent
每一個進程下N個協程,
#coding=utf-8 from multiprocessing import Process import gevent #from gevent import monkey; monkey.patch_socket() #用於協程的了程序 def yield_execFunc(x): print('______________%s'%x) #yield_clist決定協程的數量 #開始協程操做 def yield_start(yield_clist): task=[] #用來存儲協程 for i in yield_clist: task.append(gevent.spawn(yield_execFunc,i)) gevent.joinall(task) #執行協程 if __name__=="__main__": list1=[1,2,3,4,5,6,7,8,9,10] #元素個數決定開起的協程數量 list2=[1,2,3,4,5,6,7,8,9,10] list3=[1,2,3,4,5,6,7,8,9,10] process_list =[list1,list2,list3] #元素個數決定進程數量 for plist in process_list: p = Process(target=yield_start,args=(plist,)) p.start()
執行結果:開了三個進程,每一個進程下執行10個協程協做任務
C:\Python27\python.exe D:/weixin/temp/yield_tmp.py ______________1 ______________2 ______________3 ______________4 ______________5 ______________6 ______________7 ______________8 ______________9 ______________10 ______________1 ______________1 ______________2 ______________2 ______________3 ______________3 ______________4 ______________4 ______________5 ______________5 ______________6 ______________6 ______________7 ______________7 ______________8 ______________8 ______________9 ______________9 ______________10 ______________10 Process finished with exit code 0