我知道關於使用協程作爲基礎和實現玩具調度程序的基本知識。但是我認爲這是對整個異步調度器的簡單看法。我的想法中缺少一整套洞。如何實現實用的光纖調度器?
如何防止CPU運行閒置/等待的調度程序?有些光纖只是在睡覺,有些則等待操作系統的輸入。
我知道關於使用協程作爲基礎和實現玩具調度程序的基本知識。但是我認爲這是對整個異步調度器的簡單看法。我的想法中缺少一整套洞。如何實現實用的光纖調度器?
如何防止CPU運行閒置/等待的調度程序?有些光纖只是在睡覺,有些則等待操作系統的輸入。
您需要將io操作複用到基於事件的界面(選擇/輪詢)中,以便您可以利用操作系統執行等待,同時仍能夠調度其他光纖。 select/poll有一個超時參數 - 對於想要睡眠的光纖,可以創建一個優先級隊列,使用select/poll選項來模擬睡眠呼叫。
試圖服務阻止操作的光纖(呼叫讀/寫/睡眠等)。直接將無法工作,除非你安排每個光纖在本地線程 - 哪種方式擊敗了目的。
查看http://swtch.com/libtask/的工作實現。
從實現的角度來看,您可以從一個異步事件循環實現開始。然後,您可以通過使用異步事件處理程序切換到相應的光纖來實現光纖調度。
睡眠/等待光纖意味着它現在沒有安排 - 它只是切換到事件循環。
順便說一句,如果你正在尋找一些實際的代碼,看看http://svn.cmeerw.net/src/nginetd/trunk/這是工作仍然在進行中,但試圖實現對多線程事件循環的頂部(在Win32我光纖調度/ O完成端口或Linux的邊緣觸發epoll)。
您應該看看setcontext系列函數(http://en.wikipedia.org/wiki/Setcontext)。這意味着在你的應用程序中,你將需要重新實現可能阻塞(讀,寫,休眠等)爲異步形式並返回調度器的所有函數。
只有「調度器光纖」將使用select(),poll()或epoll()等待完成事件。這意味着當調度程序空閒時,進程將在select/poll/epoll調用中休眠,並且不會佔用CPU。
如何setcontext上實現這一切比較,而不依賴於機器棧呢?我可以把協程一直等到另一個協程停下來模仿簡單的調用。 – Cheery 2009-05-04 09:35:38
雖然有點遲,但我想提一下,我在C中實際使用了一個光纖庫,名爲libevfibers。
儘管是一個年輕的項目,它用於生產。它不僅爲經典的異步操作(如讀/寫套接字)提供瞭解決方案,而且還以非阻塞的方式處理文件系統IO。該項目利用了3個偉大的庫libcoro,libev和libeio。
您也可以通過使用協程來控制控制流。支持創建這些的庫是BOOST.ASIO。
一個很好的例子可以在這裏找到:Boost Stackful Coroutines
libtask看起來不錯,但它似乎不允許明確的用戶調度任務(我無法找到一個API來爲特定任務提供cpu)。我認爲boost :: context看起來更通用一些,頂層有一個名爲boost :: fiber的圖層,它實現了不同任務之間的鎖定 – lurscher 2010-11-15 15:01:53