談談協程


談談協程

關於協程,網上能看到很多資料。這里再自個梳理一下。

協程展開來說,叫做協作的程序,想表達的意思是,兩段程序,能協作地,共用公共資源,來完成兩段程序各自的目的,就叫做協程了。

把現在所有的容易混淆的名字羅列出來:並發,並行,進程,線程,協程。說說他們的歷史。

並發

首先是並發,並發的概念是很早就有的了。最早的時候機器都是批處理系統,而且是單道批處理系統,這個系統就是很簡單的線性邏輯,一個批處理任務進去,完成,然后進行下面一個。但是隨着批處理的任務越來越多,我們希望的是能一次性預存很多批處理任務進入內存,然后通過一定的處理規則指定(作業調度算法)來讓這些批處理任務划分CPU的時間,這樣CPU的狀態就像是第一秒執行A任務,第二秒執行B任務,這樣看起來,A任務和B任務就像是同時在進行。這個模式,就叫做並發了。

進程

能並發處理多任務的系統就是多道程序系統。但是有個問題是,CPU在多個批處理任務切換的過程中,對於共享變量,堆棧都需要不斷地變化和切換。那么這個時候,就引入了進程的概念,進程就是CPU處理的基本單元。每個進程有自己的上下文,堆棧,共享變量。就像一個盒子,把每個批處理任務和對應的資源都分割開了。

並行

下面,隨着CPU硬件技術的發展,一台機器上CPU的數量就不止一個了,那么這個時候,兩個CPU就可以同時,單獨處理兩個進程了。注意,這個同時才是真正的同時,那么這個模式,就叫做並行。

線程

線程的概念出現,是由於進程之前的切換需要消耗的資源太多了,很多時候,我們程序的性能都消耗在進程資源切換上了,所以我們希望的是,能不能將進程切換過程中的資源減少?這里需要深入到進程的切換,進程控制塊(PCB)是系統為了管理進程設置的一個專門的數據結構,進程切換的時候,把舊的進程的狀態存入到PCB,然后再加載裝入新的進程的PCB。PCB里面的信息包含有:程序計數器,寄存器,變量,進程資源等信息。進程之間的切換需要把這些都進行上下文切換,最麻煩耗時的就是切換頁表了,頁表中存儲的是數據段和代碼段。這里就需要線程的概念,一個進程中有多個線程,同一個進程中的線程共用代碼資源,數據資源,內存資源。所以當同一個進程中的線程進行切換的時候,我們只需要切換計數器,寄存器,變量,並不需要進行切換頁表操作,這樣,基本創建一個線程比創建一個進程速度要快10-100倍。

不管是進程切換還是線程切換,我們都需要從系統調用開始,即切換必須涉及到用戶態和內核態的函數調用。那么,就有人思考,我們是不是可以自己實現一個調度邏輯,讓線程的邏輯切換只在用戶態進行呢?這樣,線程的切換開銷就更小了,這個就是用戶態線程。

協程

下面就說到協程了。不管是怎么個做法,調度算法對於程序來說都是“被動”式的。難免會遇到這種情況,我們的程序還在IO等待中,結果調度算法把CPU的時間還分配回來給我,雖然我可以通過調度算法立即檢查並交出CPU,但是這里還是有一個切換的過程。所以就有人思考,是不是可以做成“主動式”的呢?由程序來告訴計算機,我執行到這里了,下面進行等待IO行為了,這個時候就把CPU的控制權交給別人吧。但是,這個實現的基礎當然是調度算法是用戶態的。所以,協程就是在用戶態線程中,兩個程序協商好了,通過某種方式協作運營,共享CPU控制權的方法。

一般來說,這個協商的方法通用的關鍵字就是yield。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM