協程是什麼

2022-02-04 04:06:09 字數 2297 閱讀 8061

以下是我自己的理解:

一般的執行緒切換是由作業系統來執行的,

而協程則是一種特殊的執行緒,這種執行緒的切換是由使用者自己來決定的,並且切換需要做的額外工作如:執行狀態和執行位置的儲存,也是由使用者自己來做的。

以下是乙個解釋的比較清楚的內容:

筆者最美好的記憶來自於早年在6502 cpu的cc800上寫彙編的年代, 那個時代的計算機甚至沒有作業系統,也沒有實模式等保護機制。在6502上寫彙編應用其實非常簡單,系統會把bin檔案載入到乙個固定的記憶體位址中,cpu會固定地從乙個特定的位置開始執行。然後cpu就按照你提供的機器指令開始一條一條的執行。在高階語言中的「函式呼叫」的概念,在彙編裡主要體現為兩個暫存器。暫存器是cpu內部臨時儲存資料的區域,相當於高階語言裡的變數。但是有乙個暫存器是特殊的,它存放了cpu當前正在執行的指令的記憶體位址(instruction register)。乙個高階語言中的函式一般會被編譯成指令存放在一段連續的記憶體空間中(data segment)。那麼所謂函式執行到了第幾行這樣的資訊其實就是儲存在這個instruction register中的。另外乙個很特殊的暫存器是stack register,它其中存放的記憶體位址指向的記憶體區域用於函式之間傳遞引數和返回值,以及存放乙個函式內的區域性變數。如果不考慮現代計算機cpu中各種各樣其他存放中間結果的暫存器,理論上儲存了instruction register(執行到哪兒了)和stack register(堆疊上的變數)就儲存了乙個函式的當前執行狀態,分別是函式當前執行到了哪,以及這個函式區域性變數所代表的當前state。

事實上,作業系統的幾個關鍵切換也是這麼來完成的。作業系統提供了兩個執行態,乙個是使用者態,一般我們的**都是執行在使用者態的。另外乙個是核心態,像驅動程式之類的**會用各種方式被載入到作業系統內部執行在核心之中。核心態裡的**可以完全控制cpu的i/o中斷,從而可以和外部裝置互動。使用者態的**屬於受限**,必須把i/o請求通過syscall交由執行在核心態的作業系統來完成。當乙個cpu的核在執行使用者態**時,其暫存器裡存放的狀態是你的應用的**的狀態,但是應用要進行i/o操作的時候,cpu要被切換到核心的**裡去執行核心態的**。這裡就需要進行一次context switch,所謂context switch其實原理不會比把暫存器的值存到記憶體的乙個地方,等回來的時候再把記憶體中臨時儲存的值載入回暫存器複雜多少。

作業系統還有乙個需要進行context switch的地方,那就是在協程與協程之間。作業系統在執行乙個elf或者pe的可執行檔案的時候,對於這個可執行檔案內的彙編**來說,整個記憶體定址空間是獨立的。也就是1.exe的執行狀態完全無法感知到2.exe的執行狀態的記憶體。也就是現代作業系統的虛擬記憶體空間。有cpu在兩個程序之間切換狀態的時候,需要把記憶體的對映關係調整過來,否則虛擬記憶體的位址是無法對應到正確的實體地址的。乙個程序內的兩個線成切換的時候,要稍微簡單一些,只需要把當前線成正在執行的位置和棧做切換就可以了。

無論是作業系統做user/kernel的switch,還是process/process,thread/thread的switch,其實現方式都是大同小異的。通過把「當前執行狀態」這樣的乙個抽象概念落實為乙個具體的資料結構儲存起來,然後指揮cpu在不同的場合載入不同的資料恢復不同的「當前執行狀態」。

在高階語言中,乙個函式正在執行的位置以及其狀態,內部都可以有乙個抽象的表達方式。有的高階語言直接被編譯成原生的機器碼,那麼其執行狀態的表述就和作業系統的context switch的context非常類似。有的高階語言自身執行在乙個虛擬機器之上,那麼其context的表述可能是虛擬機器的instruction register和stack register,而不是80x86這樣原生的機器的物理暫存器。但是原理是非常類似的。

取決於語言設計者的覺悟,有的語言會把這種表達執行狀態的能力直接提供出來,讓乙個函式在執行過程中可以把當前狀態儲存,然後把執行權交給另外乙個函式執行,等那個函式放棄執行權回來的時候再把儲存的狀態恢復。這也就是所謂的協程(co-routine)。協程與執行緒的區別在於,協程的context switch是在完全在使用者態,由語言的runtime或者是庫來完成的。而執行緒的context switch則是作業系統來完成的。

**:

這裡有乙個點,需要指出,文章起名【協程是「使用者態的執行緒」】,文中又有提到「一般我們的**都是執行在使用者態的」,那就是說我們隨便建立乙個簡單的執行緒,只要沒有一些類似io的系統級操作,不需要系統級的切換,那麼這個執行緒也是「使用者態的執行緒」,或者說這個執行緒會執行在使用者態下,但是這個執行緒不一定是協程。也就是說——使用者態的執行緒包含協程,但使用者態的執行緒並不一定就是協程。

額外囉嗦這些東西,希望能減輕一些人的疑惑。

Unity中的協程是什麼?

什麼是協程?1 協程是乙個分部執行,遇到條件 yield return 語句 會掛起,直到條件滿足才會被喚醒繼續執行後面的 2 unity在每一幀 frame 都會去處理物件上的協程。unity主要是在update後去處理協程 檢查協程的條件是否滿足 但也有寫特例。什麼情況是條件滿足?在協程方法中使...

什麼是協程

協程,英文coroutines,是一種比執行緒更加輕量級的存在。協程不是程序,也不是執行緒,它就是乙個可以在某個地方掛起的特殊函式,並且可以重新在掛起處繼續執行。所以說,協程與程序 執行緒相比,不是乙個維度的概念。乙個程序可以包含多個執行緒,乙個執行緒也可以包含多個協程,也就是說,乙個執行緒內可以有...

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

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