您現在的位置是:首頁 > 舞蹈首頁舞蹈

什麼是協程?

由 程式設計師雜貨鋪 發表于 舞蹈2021-09-05
簡介簡單來講協程的好處:跨平臺跨體系架構無需執行緒上下文切換的開銷無需原子操作鎖定及同步的開銷方便切換控制流,簡化程式設計模型高併發+高擴充套件性+低成本:一個CPU支援上萬的協程都不是問題

協程是什麼

最近更新比較少,內心十分的愧疚,實在是太忙了!向各位讀者說句抱歉。

今天要講的這個東西說實話,我也是今天才知道,一個我們大多數人可能從來都沒用過的語法,哪就是傳說中的【協程 Coroutine】。

可能你會說,攜程誰不知道啊,不就是哪個用來訂機票訂酒店的軟體麼,這有什麼好學的!這樣的話你就錯了,此協程非彼攜程,可不要傻傻分不清楚嘍!

什麼是程序和執行緒

程序是什麼

直白地講,程序就是應用程式的啟動例項。比如我們執行一個遊戲,開啟一個軟體,就是開啟了一個程序,程序擁有程式碼和開啟的檔案資源、資料資源、獨立的記憶體空間。

執行緒又是什麼

執行緒從屬於程序,是程式的實際執行者。一個程序至少包含一個主執行緒,也可以有更多的子執行緒,執行緒擁有自己的棧空間。

執行緒具有五種狀態:

什麼是協程?

對作業系統來說,執行緒是最小的執行單元,程序是最小的資源管理單元。

無論程序還是執行緒,都是由作業系統所管理的。

程序和執行緒的痛點

執行緒之間是如何進行協作的呢?

最經典的例子就是

生產者/消費者模式

若干個生產者執行緒向佇列中寫入資料,若干個消費者執行緒從佇列中消費資料。

什麼是協程

官方定義如下:

A coroutine is a

function

that can

suspend

its execution (yield) until the given given

YieldInstruction

finishes。

用我蹩腳的英語來翻譯一下就是:

學過計算機組成原理的都知道,當 CPU 在多個程序間切換時,那些後臺程式就會處於這種暫停用英文的 Suspend 或許更恰當)的狀態,所以早年的電腦即使用一個 CPU 也可以同時處理多個程序任務,這是一種“偽多執行緒”的技術。

除此之外比較重要的一點是,協程不是被作業系統核心所管理,而完全是由程式所控制(也就是在使用者態執行)。這樣帶來的好處就是效能得到了很大的提升,不會像執行緒那樣需要上下文切換來消耗資源,因此

協程的開銷遠遠小於執行緒的開銷

注意

,這裡要劃一個重點,

協程是一種“偽多執行緒”

,始終記得這一點,可以幫助我們來理解協程會這個概念。

協程函式的寫法

Java 語言

並沒有對協程提供原生支援,所以用 Java 暫時還演示不了,但是有個開源框架基本模擬除了協程的功能,感興趣的朋友可以去看看原始碼。。。

地址 :https://github。com/kilim/kilim

Go 語言

根據我查詢資料來看,對於協程的支援超乎我的想象,可以說是強大而簡潔,輕輕鬆鬆分分鐘建立成百上千個協程併發執行。

func Add(x, y int) { z := x + y fmt。Println(z)} func main() { for i:=0; i<10; i++ { go Add(i, i) }}

如上程式碼,在一個函式呼叫前加上 go 關鍵字,這次呼叫就會在一個新的協程中併發執行。當被呼叫的函式返回時,這個協程也自動結束。需要注意的是,如果這個函式有返回值,那麼這個返回值會被丟棄。

Python 語言也可以透過 yield/send 的方式實現協程。在 python 3。5 以後,async/await 成為了更好的替代方案。

def consume(): while True: # consumer 協程等待接收資料 number = yield print(“開始消費”,number) consumer = consume()# 讓初始化狀態的 consumer 協程先執行起來,在 yield 處停止next(consumer)for num in range(0,100) print(“開始生產”,num) # 傳送資料給 consumer 協程 consumer。send(num)

其他語言的寫法我也就不寫了,畢竟不太熟,寫了怕誤人子弟!!!

總結

根據今天查閱的資料來看,協程的應用場景主要在於 :I/O 密集型任務。

這一點與多執行緒有些類似,但協程呼叫是在一個執行緒內進行的,是單執行緒,切換的開銷小,因此效率上略高於多執行緒。當程式在執行 I/O 時操作時,CPU 是空閒的,此時可以充分利用 CPU 的時間片來處理其他任務。在單執行緒中,一個函式呼叫,一般是從函式的第一行程式碼開始執行,結束於 return 語句、異常或者函式執行(也可以認為是隱式地返回了 None )。 有了協程,我們在函式的執行過程中,如果遇到了耗時的 I/O 操作,函式可以臨時讓出控制權,讓 CPU 執行其他函式,等 I/O 操作執行完畢以後再收回控制權。

簡單來講協程的好處:

跨平臺

跨體系架構

無需執行緒上下文切換的開銷

無需原子操作鎖定及同步的開銷

方便切換控制流,簡化程式設計模型

高併發+高擴充套件性+低成本:一個CPU支援上萬的協程都不是問題。所以很適合用於高併發處理。

缺點:

無法利用多核資源:協程的本質是個單執行緒,它不能同時將 單個CPU 的多個核用上,協程需要和程序配合才能執行在多CPU上。當然我們日常所編寫的絕大部分應用都沒有這個必要,除非是cpu密集型應用。

進行阻塞(Blocking)操作(如IO時)會阻塞掉整個程式:這一點和事件驅動一樣,可以使用非同步IO操作來解決

最後再貼個圖來總結一下,更清楚:

什麼是協程?

本文首發於微信公眾號 【程式猿雜貨鋪】,關注公眾號,獲取更多精彩文章!