什麼是協程

2021-10-12 09:20:42 字數 1586 閱讀 4378

協程,英文coroutines,是一種比執行緒更加輕量級的存在。

協程不是程序,也不是執行緒,它就是乙個可以在某個地方掛起的特殊函式,並且可以重新在掛起處繼續執行。所以說,協程與程序、執行緒相比,不是乙個維度的概念。

乙個程序可以包含多個執行緒,乙個執行緒也可以包含多個協程,也就是說,乙個執行緒內可以有多個那樣的特殊函式在執行。但是有一點,必須明確,乙個執行緒內的多個協程的執行是序列的。如果有多核cpu的話,多個程序或乙個程序內的多個執行緒是可以並行執行的,但是乙個執行緒內的多個協程卻絕對序列的,無論有多少個cpu(核)。這個比較好理解,畢竟協程雖然是乙個特殊的函式,但仍然是乙個函式。乙個執行緒內可以執行多個函式,但是這些函式都是序列執行的。當乙個協程執行時,其他協程必須掛起。

表面上,程序、執行緒、協程都存在上下文切換的問題,但是三者上下文切換又有明顯不同,見下表:

協程、執行緒、程序的比較 程序

執行緒協程

切換者操縱系統

作業系統

使用者(程式設計者/應用程式)

切換時機

根據作業系統自己的切換策略,使用者不感知

根據作業系統自己的切換策略,使用者不感知

使用者(的程式)自己決定

切換內容

頁全域性目錄

核心棧硬體上下文

核心棧硬體上下文

硬體上下文

切換內容的儲存

儲存於核心棧中

儲存於核心棧中

儲存於使用者自己的變數(使用者棧/堆)

切換過程

使用者態-核心態-使用者態

使用者態-核心態-使用者態

使用者態(沒有陷入核心態)

切換效率

乙個執行緒內的多個協程是序列執行的,不能利用多核,所以,顯然,協程不適合計算密集型的場景。協程適合i/o 阻塞型。

i/o本身就是阻塞型的(相較於cpu的時間世界而言)。就目前而言,無論i/o的速度多快,也比不上cpu的速度,所以乙個i/o相關的程式,當其在進行i/o操作時候,cpu實際上是空閒的。

我們假設這樣的場景,如下圖:1個執行緒有5個i/o的事情(子程式)要處理。如果我們絕對的序列化,那麼當其中乙個i/o阻塞時,其他4個i/o並不能得到執行,因為程式是絕對序列的,5個i/o必須乙個乙個排隊等待處理,當乙個i/o阻塞時,其它4個也得等著。

而協程能比較好地處理這個問題,當乙個協程(特殊子程序)阻塞時,它可以切換到其他沒有阻塞的協程上去繼續執行,這樣就能得到比較高的效率,如下圖所示:

上面舉的例子是5個i/o處理,如果每秒500個,5萬個或500萬個呢?已經達到了「i/o密集型」的程度,而「i/o密集型」確實是協程無法應付的,因為它沒有利用多核的能力。這個時候的解決方案就是「多程序+協程」了。

所以說,i/o阻塞時,利用協程來處理確實有優點(切換效率比較高),但是我們也需要看到其不能利用多核的這個缺點,必要的時候,還需要使用綜合方案:多執行緒+協程。

什麼是協程?協程的優缺點

協程 協程是微執行緒,纖程,本質是乙個單執行緒 協程能在單執行緒處理高併發,因為遇到 i o 自動切換,執行緒遇到 i o 操作會等待 阻塞。協程的優缺點 缺點 缺點是無法利用多核資源,本質是單核的,它不能同時將單個cpu的多個核用上,協程需要和程序配合才能執行在多cpu上。優點 不僅是處理高併發 ...

協程是什麼

以下是我自己的理解 一般的執行緒切換是由作業系統來執行的,而協程則是一種特殊的執行緒,這種執行緒的切換是由使用者自己來決定的,並且切換需要做的額外工作如 執行狀態和執行位置的儲存,也是由使用者自己來做的。以下是乙個解釋的比較清楚的內容 筆者最美好的記憶來自於早年在6502 cpu的cc800上寫彙編...

協程巢狀協程

import asyncio import functools 第三層協程 async def test1 print 我是test1 await asyncio.sleep 1 print test1已經睡了1秒 await asyncio.sleep 3 print test1又睡了3秒 ret...