什么是IOCP

IOCP(Input/Output Completion Port)是一种高效的异步I/O模型,常用于多线程环境。它通过一个完成端口对象管理和通知多个并发的I/O操作,线程池中的线程从IOCP队列中获取完成通知并处理数据。IOCP结合了重叠I/O和事件通知,如WSASend和WSARecv,用于异步发送和接收数据。使用IOCP可以实现负载均衡,减少线程上下文切换的开销,提高系统性能。
摘要由CSDN通过智能技术生成

百度词条

输入输出完成端口(Input/Output Completion Port,IOCP), 是支持多个同时发生的异步I/O操作的应用程序编程接口
一个IOCP对象,在操作系统中可关联着多个Socket和(或)文件控制端。 IOCP对象内部有一个先进先出(FIFO)队列,用于存放IOCP所关联的输入输出端的服务请求完成消息。请求输入输出服务的进程不接收IO服务完成通知,而是检查IOCP的消息队列以确定IO请求的状态。 (线程池中的)多个线程负责从IOCP消息队列中取走完成通知并执行数据处理;如果队列中没有消息,那么线程阻塞挂起在该队列。

通俗易懂

我们先开好N个线程,一般情况下线程的数量与CPU内核数量相同,一开始这些线程并不运行;
用户将请求都发送到一个 完成端口 上,这N个线程从 完成端口 上取得这些请求并处理。
这样可以避免频繁的打开、关闭线程,并且可以提高线程的利用率(因为线程是不断地再循环获取完成端口上的请求,理论上说只要完成端口的请求不为空,线程的利用率就是100%)

在这里插入图片描述

重叠IO模型

在这里插入图片描述
重叠模型是让应用程序使用重叠数据结构(WSAOVERLAPPED),一次投递一个或多个Winsock I/O请求,针对这些提交的请求,在他们完成之后,应用程序会收到通知,于是就可通过自己的代码来处理这些数据了。

使用事件通知的方法来实现重叠IO模型,基于事件的话,就要求将Win事件与WSAOVERLAPPED结构关联在一起

使用重叠结构,常用的send,sendto,recv,recvform也被WSASend,WSARecv等替换掉,
OVERLAPPER SOCKET(重叠Socket)上进行重叠发送的操作,(简单的理解就是异步send,recv)
他们的参数中都有一个Overlapped参数,就是说所有的重叠Socket都要绑定到这个重叠结构体上,
提交一个请求,其他的事情就交给重叠结构去操心, 而其中重叠结构要与Windows事件绑定在一起, 这样,我们调用完WSARecv后.等重叠操作完成,就会有对应的事件来同意我们操作完成,

WSARecv函数:
从一个套接口接收数据的程序。主要用于在重叠模型中接收数据。
WSASend函数:
在一个已连接的套接口上发送数据。
AcceptEx函数(listen_handle, accept_handle):
Windows套接字AcceptEx函数接受一个新的连接,返回本地和远程地址,并接收由客户端应用程序发送的第一块数据。
listen_handle 侦听套接字。服务器应用程序在这个套接字上等待连接。
accept_handle 将用于连接的套接字。此套接字必须不能已经绑定或者已经连接。
WSAConnect函数:
创建一个与远端的连接,交换连接数据,并根据所提供的流描述确定所需的服务质量。

常用套接字选项(SOL_SOCKET级别)

IOCP结构

在这里插入图片描述

一共包括三部分:
  完成端口(存放重叠的I/O请求),客户端请求的处理,等待者线程队列(一定数量的工作者线程,一般采用CPU*2个)
  完成端口中所谓的[端口]并不是我们在TCP/IP中所提到的端口,可以说是完全没有关系。它其实就是一个通知队列,由操作系统把已经完成的重叠I/O请求的通知放入其中。当某项I/O操作一旦完成,某个可以对该操作结果进行处理的工作者线程就会收到一则通知。
  通常情况下,我们会在创建一定数量的工作者线程来处理这些通知,也就是线程池的方法。线程数量取决于应用程序的特定需要。理想的情况是,线程数量等于处理器的数量,不过这也要求任何线程都不应该执行诸如同步读写、等待事件通知等阻塞型的操作,以免线程阻塞。每个线程都将分到一定的CPU时间,在此期间该线程可以运行,然后另一个线程将分到一个时间片并开始执行。如果某个线程执行了阻塞型的操作,操作系统将剥夺其未使用的剩余时间片并让其它线程开始执行。也就是说,前一个线程没有充分使用其时间片,当发生这样的情况时,应用程序应该准备其它线程来充分利用这些时间片。
  
总结:
  线程池中的工作线程的数量与CPU内核数量相同,以此来最小化线程切换代价。一个IOCP对象,在操作系统中可关联着多个Socket和(或)文件控制端。 IOCP对象内部有一个先进先出(FIFO)队列,用于存放IOCP所关联的输入输出端的服务请求完成消息。请求输入输出服务的进程不接收IO服务完成通知,而是检查IOCP的消息队列以确定IO请求的状态。 (线程池中的)多个线程负责从IOCP消息队列中取走完成通知并执行数据处理;如果队列中没有消息,那么线程阻塞挂起在该队列。这些线程从而实现了负载均衡。

IOCP参考文章1
IOCP参考文章2

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值