IOCP的一些心得


  1. IOCP的工作線程的個數一般設置為processors *2+2,這是綜合考慮了工作線程可能是等待/掛起/正在執行的狀態。如果你測試出更好的結果,以你的為標准。
  2. IOCP的工作線程由系統調度和優化,不要去干預線程的調度,除非你自信能超越系統的調度。
  3. 在遇到奇怪的問題時,可以嘗試減少IOCP工作線程數量,來定位問題所在。
  4. 應用層在處理收到的數據時,盡快將數據處理掉或是拷貝一份,避免阻塞IOCP工作線程。
  5. 在投遞I/O和收到該I/O完成通知(不管成功失敗)期間,注意保存好Overlapped I/O結構,以免出現奇怪的內存問題。
  6. 在投遞I/O時,如果返回WSA_IO_PENDING,意味着投遞操作成功,但是稍后才會處理完成。一般說來,投遞發送或接收IO請求可能是下面三種結果, 以調用WSASend為例:
    I.如果操作錯誤碼是ERROR_SUCCESS,系統將程序緩沖區拷貝到內核緩沖區(也就是TCP/IP棧緩沖區)中,然后在網絡適當的時候(比如符合Nagle算法的發送條件),將數據拷貝到網卡緩沖區,進行真正的發送;
    II.如果操作錯誤碼是WSA_IO_PENDING,意味着此時內核緩沖區空間不夠,系統將鎖定程序緩沖區鎖定到非分頁內存中,直到內核緩沖區有足夠的空間來將數據拷貝走;
    III.如果操作結果是其他錯誤碼,根據具體原因,可以選擇釋放socket對應的資源。(該條目參考《Windows網絡編程第2版》)
  7. 盡量使I/O緩沖區的大小是系統頁面大小的倍數(32位是4k),這樣避免系統在拷貝程序緩沖區在不足一倍數時而占用整個頁面。
  8. 盡量投遞大型I/O操作,也就是每次發送較大的數據包,而不是多次發送一些小的數據包,且每次發送數據都固定大小。
  9. 使用AcceptEx異步接收的連接,如果要獲取本地/對端的地址,有兩種方式:
    I.使用擴展API:GetAcceptExSockaddrs,可以同時獲取本地/對端地址,需要I/O結構的支持;
    II.使用標准API:getsockname/getpeername,由於對端socket尚未與監聽socket完全綁定,需要先設置SO_UPDATE_ACCEPT_CONTEXT 選項,然后才可以正常獲取到。(適用於winxp以后的版本)
  10. 在關閉Socket時,注意處理未決的IO請求,這些請求以失敗的結果(GetQueuedCompletionStatus失敗)返回。
  11. 常見錯誤碼:
    ERROR_NETNAME_DELETED(64):對端關閉socket
    ERROR_OPERATION_ABORTED(995):本端socket被關閉,操作取消

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com