協程主要用於高io的操作的**中,例如爬蟲,如果只是單個的計算**,不建議使用協程。
程序:啟動多個程序 程序之間是由作業系統負責呼叫
執行緒:啟動多個執行緒 真正被cpu執行的最小單位實際是執行緒
開啟乙個執行緒 建立乙個執行緒 暫存器 堆疊
關閉乙個執行緒
協程:本質上就是乙個執行緒
能夠在多個任務之間切換來節省一些io時間
協程中任務之間的切換也消耗時間,但是開銷要遠遠小於程序執行緒之間的切換
協程模組,是使用greenlet
封裝好的模組,所以要先安裝兩個包,greenlet
、gevent
from greenlet import greenlet
defeat()
:print
('eating start'
) g2.switch(
)print
('eating end'
) g2.switch(
)def
play()
:print
('playing start'
) g1.switch(
)print
('playing end'
)g1 = greenlet(eat)
g2 = greenlet(play)
g1.switch(
)
輸出:
switch()
函式起的是在多工中進行切換的作用,且switch()
是順序執行的。g1
執行完,個g2
執行,詳細的執行順序,需要看**是怎麼寫的。
常用方法
g1 = gevent.spawn(func,1,2,3,x=4,y = 5)
建立乙個協程物件,第乙個引數是執行的函式,後面可以有多個引數,可以是位置引數也可以是關鍵字引數。
g1.join()
等待g1執行結束
g1.value
當g1有返回值時,可以用value發給發的到func的返回值
from gevent import monkey;monkey.patch_all(
)import gevent,time
defeat()
:print
('eating start'
)# time.sleep(1)
gevent.sleep(1)
print
('eating end'
)def
play()
:print
('playing start'
)# time.sleep(1)
gevent.sleep(1)
print
('playing end'
)g1 = gevent.spawn(eat)
g2 = gevent.spawn(play)
g1.join(
)g2.join(
)
輸出:
當在寫協程**的時候使用from gevent import monkey;monkey.patch_all()
,把這一句寫在最上面一層,會把下面匯入的一些包打包起來,讓協程的**能夠認識。當沒有這句話的時候,time包不能被協程的**認識,不能成功執行,只能忍受gevent.sleep(1)
。如果寫入了這句話,就可以直接執行time.sleep(1)
。
當協程遇到協程模組能識別的io操作的時候,協程任務之間的切換由程式(**)完成。
程序和執行緒的任務切換是由作業系統的時間片輪轉來完成的。
協程巢狀協程
import asyncio import functools 第三層協程 async def test1 print 我是test1 await asyncio.sleep 1 print test1已經睡了1秒 await asyncio.sleep 3 print test1又睡了3秒 ret...
9 協程 協程理論
本節的主題是基於單執行緒來實現併發,即只用乙個主線程 很明顯可利用的cpu只有乙個 情況下實現併發,為此我們需要先回顧下併發的本質 切換 儲存狀態 ps 在介紹程序理論時,提及程序的三種執行狀態,而執行緒才是執行單位,所以也可以將上圖理解為執行緒的三種狀態cpu正在執行乙個任務,會在兩種情況下切走去...
python協程與非同步協程
在前面幾個部落格中我們一一對應解決了消費者消費的速度跟不上生產者,浪費我們大量的時間去等待的問題,在這裡,針對業務邏輯比較耗時間的問題,我們還有除了多程序之外更優的解決方式,那就是協程和非同步協程。在引入這個概念之前我們先看 看這個圖 從這個我們可以看出來,假如來了9個任務,即使我們開了多程序,在業...