IOCP 的一些问题总结

  1. IOCP的工做线程的个数通常设置为processors *2+2,这是综合考虑了工做线程多是等待/挂起/正在执行的状态。若是你测试出更好的结果,以你的为标准。算法

  2. IOCP的工做线程由系统调度和优化,不要去干预线程的调度,除非你自信能超越系统的调度。编程

  3. 在遇到奇怪的问题时,能够尝试减小IOCP工做线程数量,来定位问题所在。网络

  4. 应用层在处理收到的数据时,尽快将数据处理掉或是拷贝一份,避免阻塞IOCP工做线程。app

  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版》)
    socket

  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之后的版本)
    spa

  10. 在关闭Socket时,注意处理未决的IO请求,这些请求以失败的结果(GetQueuedCompletionStatus失败)返回。线程

  11. 常见错误码:ERROR_NETNAME_DELETED(64):对端关闭socketERROR_OPERATION_ABORTED(995):本端socket被关闭,操做取消

相关文章
相关标签/搜索