2010-05-06 84 views
5

我使用epoll/devpoll/kqueue/poll/select(包括windows-select)爲異步套接字IO設計事件循環。異步事件循環設計和問題

我有表演的兩個選項,IO操作:在EAGAIN

非阻塞模式,調查

  1. 設置套接字非阻塞模式。
  2. 讀/寫入套接字。
  3. 如果操作成功,則向事件循環發佈完成通知。
  4. 如果我得到EAGAIN,將套接字添加到「選擇列表」並輪詢套接字。

輪詢方式:輪詢,然後執行

  1. 添加插座選擇列表和輪詢它。在正常模式下使用時
  2. 等待通知,這是可讀可寫的
  3. 讀/寫
  4. 後完成通知sucseeds的事件循環

對我來說,它看起來像第一次將需要更少的系統調用, 尤其適用於寫入套接字(緩衝區相當大)。 此外,它看起來可以減少「select」 執行次數的開銷,特別是當你沒有可以很好地擴展爲epoll/devpoll/kqueue的東西 時更是如此。

問題:

  • 有沒有第二個方法的任何好處?
  • 在Linux,FreeBSD,Solaris,MacOSX,Windows等衆多操作系統上,套接字/文件描述符上的非阻塞操作是否存在可移植性問題。

注:請不要建議使用現有的事件環/插座-API實現

回答

3

我不知道有任何跨平臺的問題;最多隻能使用Windows套接字API,但結果相同。

否則,你似乎在任何情況下輪詢(避免阻塞等待),所以這兩種方法都很好。只要你沒有阻止自己的位置(例如,當沒有數據時讀取,當緩衝區已滿時寫入),它根本沒有任何區別。

也許第一種方法更容易編碼/理解;所以,去那。

您可能有興趣查看關於此主題的有趣想法/方法的文檔libevc10k problem

2

第一個設計是Proactor Pattern,二是反應器模式的Reactor Pattern

一個好處是,你可以設計自己的API,這樣你就不必分配讀緩衝區,直到數據實際上是有被閱讀。這可以減少您在等待I/O時的內存使用量。

+0

我看不出有什麼理由不能等待分配內存直到需要使用第一種方法。我錯過了什麼嗎? – Ioan 2010-05-10 18:47:59

+2

我想是這樣,但實際上並沒有這樣實現。在第一種情況下,您需要步驟2-4中提供的緩衝區,在第二種情況下,您只需要在步驟3中使用緩衝區。 – karunski 2010-05-16 19:14:43

1

我與低延遲插座應用經驗:

的寫入 - 嘗試直接從寫線程寫入插座(您需要獲得該事件的循環互斥體),如果寫不完整訂閱寫就緒帶有事件循環(select/waitformultipleobjects),並在套接字可寫時從事件循環線程寫入

讀取 - 總是「訂閱」所有套接字的讀取準備就緒,因此您總是在套接字獲取時從事件循環線程中讀取可讀