協程初探

weixin_34402090發表於2014-08-27

文章出處:http://blog.csdn.net/lanphaday/archive/2010/03/19/5397038.aspx

 

    協程,又稱微執行緒和纖程等,據說源於 Simula 和 Modula-2 語言(我沒有深究,有錯請指正),現代程式語言基本上都有支援,比方 Lua、ruby 和最新的 Google Go,當然也還有近期非常讓我驚豔的 falcon。協程是使用者空間執行緒,作業系統對其存在一無所知,所以須要使用者自己去做排程,用來執行協作式多工非常合適。其有用協程來做的東西,用執行緒或程式通常也是一樣能夠做的,但往往多了很多加鎖和通訊的操作。

 

以下是生產者消費者模型的基於搶佔式多執行緒程式設計實現(虛擬碼):
// 佇列容器 var q := new queue // 消費者執行緒 loop lock(q) get item from q unlock(q) if item use this item else sleep // 生產者執行緒 loop create some new items lock(q) add the items to q unlock(q)

由以上程式碼能夠看到執行緒實現至少有兩點硬傷:

1、對佇列的操作須要有顯式/隱式(使用執行緒安全的佇列)的加鎖操作。

2、消費者執行緒還要通過 sleep 把 CPU 資源適時地“謙讓”給生產者執行緒使用,當中的適時是多久,基本上僅僅能靜態地使用經驗值,效果往往不由人意。

而使用協程能夠比較好的解決問題,以下來看一下基於協程的生產者消費者模型實現(虛擬碼):// 佇列容器 var q := new queue // 生產者協程 loop while q is not full create some new items add the items to q yield to consume // 消費者協程 loop while q is not empty remove some items from q use the items yield to produce

    可以從以上程式碼看到之前的加鎖和謙讓 CPU 的硬傷不復存在,但也損失了利用多核 CPU 的能力。所以選擇執行緒還是協程,就要看應用場合了。以下簡單談一下協程常見的用武之地,當中之中的一個是狀態機,可以產生更高可讀性的程式碼;還有就是並行的角色模型,這在遊戲開發中比較常見;以及產生器,有助於對輸入/輸出和資料結構的通用遍歷。

    協程儘管如此之好,看是非常長時間以來,由於受到基於堆疊的子例程實現的限制,並沒有多少語言在事實上語言或庫中支援協程,所以執行緒作為一個替代者(當然,執行緒也有其超越協程之處)被廣泛接受了。可是在今天,非常多語言都內建了協程的支援,甚至是 C/C++ 語言。MS Windows 2000 以後的版本號,都支援所謂的 Fiber,即纖程,事實上就是協程的別稱;在開源平臺,POSIX 標準也定義了協程相關的標準,GNU Portable Threads 實現了跨平臺的使用者空間執行緒,即協程的還有一種別稱。在這百花齊放的時節,正是我們好好學習和利用它的時機。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相關文章