協程(一)原理

轉自賴勇浩(http://laiyonghao.com)編程

協程,又稱微線程和纖程等,聽說源於 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)ruby

由以上代碼能夠看到線程實現至少有兩點硬傷:數據結構

一、對隊列的操做須要有顯式/隱式(使用線程安全的隊列)的加鎖操做。多線程

二、消費者線程還要經過 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 produceoop

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

協程雖然如此之好,看是很長時間以來,由於受到基於堆棧的子例程實現的限制,並無多少語言在其實語言或庫中支持協程,因此線程做爲一個替代者(固然,線程也有其超越協程之處)被普遍接受了。可是在今天,不少語言都內建了協程的支持,甚至是 C/C++ 語言。MS Windows 2000 之後的版本,都支持所謂的 Fiber,即纖程,其實就是協程的別稱;在開源平臺,POSIX 標準也定義了協程相關的標準,GNU Portable Threads 實現了跨平臺的用戶空間線程,即協程的另外一種別稱。在這百花齊放的時節,正是咱們好好學習和利用它的時機。this

接下來我將在第二篇中談談遊戲中試用協程的三個場合。操作系統

相關文章
相關標籤/搜索