我试图理解为什么使用IOCP。我能想到两个原因:
WSARecv()不会阻塞,所以我可以处理1000 s的客户端,而不必为每个客户端创建一个新线程(而且,您可以创建多少个线程是有限制的,因此您可以处理的客户机数量将是有限的)。WSASend()不会阻塞,所以当我想发送一个大文件时,我不需要创建一个新线程来发送它(如果我没有创建一个新线程,那么UI线程当然会阻塞)。使用IOCP还有什么其他原因?
发布于 2015-05-28 09:35:58
IOCP有您提到的优点,但这并不是IOCP独有的。我不太熟悉原生套接字API,但有些Win32 API有“重叠IO”,这是异步的,但不需要IOCP。
另一个好处是,使用IOCP,请求服务线程的数量由内核优化(某种程度上)。内核知道所有阻塞服务线程的请求,它将确保在任何时候都有足够的、而不是更多的线程解除阻塞,以便CPU得到很好的利用。理想情况下,您永远不会阻塞和有内核一样多的线程(假设100%负载)。那将是非常有效的。
IOCP还有助于减少上下文切换,因为它不是切换到另一个线程来处理IO的结果,而是一个现有的线程正忙着再次调用GetQueuedCompletionStatus。
GetQueuedCompletionStatusEx可以用于减少到内核的转换次数,因为您可以在一个调用中解除多个IOs的队列。
发布于 2015-05-28 09:38:29
此外,它减少了可避免的批量数据复制和保护环循环。当recv()调用请求时,内核不必将数据从网络堆栈缓冲区复制到用户空间缓冲区中,而是由WSARecv()提供用户空间缓冲区,然后堆栈可以直接将它们加载到内核空间。
https://stackoverflow.com/questions/30501256
复制相似问题