Windows IOCP文档建议每个可用内核每个完成端口不要超过一个线程。超线程使核心数量翻倍。由于使用IOCP会导致出于事实驱动应用程序的所有实际目的,因此使用线程池会给调度程序添加不必要的处理。
如果你仔细考虑它,你就会明白为什么:一个事件应该尽可能快地完整服务(或者在初始处理后放置在某个队列中)。假设五个事件在四核计算机上排队到IOCP。如果有八个线程与IOCP相关联,那么您将面临调度程序中断一个事件的风险,即通过使用效率低下的另一个线程开始服务另一个事件。如果中断的螺纹位于关键部分内,也可能很危险。使用四个线程,您可以同时处理四个事件,只要一个事件完成,您就可以从IOCP队列中最后一个事件开始。
当然,您可能有用于非IOCP相关处理的线程池。
编辑 __ _ __ _ __ _ __ _ __ _ _
套接字(文件句柄工作也没关系)与IOCP关联。完成例程在IOCP上等待。一旦请求读取或写入套接字完成操作系统 - 通过IOCP - 释放等待IOCP的完成例程并返回您在调用读取或写入时提供的附加信息(我通常将指针传递给一个控制块)。所以完成程序立即“知道”在哪里找到与完成有关的信息。
如果您传递的是涉及控制块(类似)的信息,那么该控制块(可能)需要跟踪已完成的操作,以便知道下一步该做什么。 IOCP本身既不知道也不关心。
如果您正在编写连接到互联网的服务器,服务器将发出读取以等待客户端输入。该输入可能会在毫秒或一周后到达,当它输入时,IOCP将释放分析输入的完成例程。通常情况下,它会响应包含输入中请求的数据的写入,然后等待IOCP。写操作完成后,IOCP再次释放完成程序,该程序发现写操作已完成,通常会发出新读操作并开始新的循环。
因此,一个基于IOCP的应用程序通常会消耗非常少(或不)的CPU,直到完成发生时为止,此时完成例程完全倾斜,直到完成处理,发送新的I/O请求并再次等待在完成端口。除了IOCP超时(可以用来表示内务管理等)之外,所有I/O相关的事情都发生在操作系统中。
为了使事情进一步复杂化(或简化),使用WSA例程无需使用套接字,Win32函数ReadFile和WriteFile工作得很好。
为什么要避免同步事件? – nitzanms