什麼是協程

付威的網路部落格發表於2019-07-14

協程(Coroutine)又稱為微執行緒,我們知道執行緒是CPU的執行的最小單位,執行緒執行的最小程式碼單位是方法。

比如在執行的時候,一個執行緒從程式的入口呼叫Main方法,Main呼叫A方法,A方法又呼叫B方法,整個的執行完成的順序是B->A->Main。這個呼叫的順序是明確的,是通過壓棧和出棧的方式確定的。

而協程不同, Main呼叫B,在呼叫B的過程中可以中斷,Main函式繼續執行一會,Main再中斷,B繼續再執行一會, 繼續執行的程式碼是上次中斷的地方。

用虛擬碼表示兩個方法:

funcA(){
     funcB();
     print 4;
     print 5;
     print 6;
}
funcB(){
     print 1;
     print 2;
     print 3;
}

如果是用正常的單執行緒執行緒來執行的時候,列印結果是123456,如果採用協程,列印結果就有可能是142536.

協程的執行的結果有點和多執行緒類似,但本質與多執行緒不同,執行緒有上下文切換,存在變數的拷貝,而協程只是輕量級的方法中斷,所以切換效率是高於執行緒。

協程所有的變數都是共享記憶體,訪問不需要加鎖,使用時只需簡單的判斷,不存線上程不安全問題。

在java中,還不支援協程的機制,所以用C#來演示下協程的過程。

 

 static void Main(string[] args)
     {
          System.Console.WriteLine("執行方法:Main");
          IEnumerable<int> intList = Xc.GetList();
          foreach (int i in intList)
          {
               System.Console.WriteLine("協程1:執行");
               Console.WriteLine("協程1:獲得返回的結果是:" + i);
          }
     }

     class Xc
     {
          public static IEnumerable<int> GetList()
          {
               System.Console.WriteLine("執行方法:GetList");
               for (int i = 0; i < 10; i++)
               {
                    yield return i;
                    System.Console.WriteLine("協程2: 執行");
                    System.Console.WriteLine("協程2:doSomething");
                    Thread.Sleep(1000);
               }
          }
     }

執行結果如下:

 

     執行方法:Main
     執行方法:GetList
     協程1:執行
     協程1:獲得返回的結果是:0
     協程2: 執行
     協程2:doSomething
     協程1:執行
     協程1:獲得返回的結果是:1
     協程2: 執行
     協程2:doSomething
     協程1:執行
     協程1:獲得返回的結果是:2

 

 從上面的結果可以看出,在協程1迴圈執行的時,Main方法會中斷,執行GetList方法,執行GetList到達約定中斷點,Main方法又繼續執行。

相關文章