【问题标题】:Why IOCP is used?为什么使用 IOCP?
【发布时间】:2015-08-10 15:33:33
【问题描述】:

我想了解为什么要使用 IOCP。我能想到两个原因:

  • 由于WSARecv() 不会阻塞,所以我可以处理 1000 多个客户端,而无需为每个客户端创建一个新线程(此外,您可以创建的线程数量以及您创建的客户端数量都有限制可以处理将受到限制)。
  • 既然WSASend()不会阻塞,那么当我要发送一个大文件时,我不必创建一个新线程来发送它(如果我没有创建一个新线程那么UI线程会阻塞当然)。

还有哪些使用 IOCP 的理由?

【问题讨论】:

  • 当然,没有成千上万的线程等待 I/O 完成才是重点。这无法扩展,线程太贵了。

标签: c sockets winapi iocp overlapped-io


【解决方案1】:

IOCP 具有您提到的好处,但这并不是 IOCP 独有的。我对原生套接字 API 不是很熟悉,但一些 Win32 API 有“重叠 IO”,它是异步的,但不需要 IOCP。

另一个好处是,使用 IOCP,请求服务线程的数量(在某种程度上)由内核优化。内核知道请求服务线程所做的所有阻塞,它会确保始终有足够多的线程未被阻塞,以便充分利用 CPU。理想情况下,您永远不会阻塞,并且线程数与内核数一样多(假设负载为 100%)。这样效率会很高。

IOCP 还有助于减少上下文切换,因为不是切换到另一个线程来处理 IO 的结果,而是已经很忙的现有线程只需再次调用 GetQueuedCompletionStatus

GetQueuedCompletionStatusEx 可用于减少到内核的转换次数,因为您可以在一次调用中使多个 IO 出列。

【讨论】:

【解决方案2】:

此外,它还减少了可避免的批量数据复制和保护环周期。当 recv() 调用请求时,内核不必将数据从网络堆栈缓冲区复制到用户空间缓冲区,用户空间缓冲区由 WSARecv() 提供,然后堆栈可以直接将它们加载到内核空间中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多