2

我试图了解为什么使用 IOCP。我可以想到两个原因:

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

使用 IOCP 还有哪些其他原因?

4

2 回答 2

2

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

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

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

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

于 2015-05-28T09:35:58.923 回答
1

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

于 2015-05-28T09:38:29.803 回答