overview
这个字符到底是什么含义呢?
其实它的意思就是当程序在等待设备操作的时候,可以继续往下做而不必阻塞到那个地方等待设备操作的返回,这就造成了程序运行和设备操作时间上的重叠。
Overlapped I/O也称Asynchronous I/O,异步I/O模型。异步I/O和同步I/O不同,同步I/O时,程序被挂起,一直到I/O处理完,程序才能获得控制。异步I/O,调用一个函数告诉OS,进行I/O操作,不等I/O结束就立即返回,继续程序执行,操作系统完成I/O之后,通知消息给你。Overlapped I/O只是一种模型,它可以由内核对象(hand),事件内核对象(hEvent), 异步过程调用(apcs) 和完成端口(I/O completion)实现。
Overlapped I/O的设计的目的:
取代多线程功能,(多线程存在同步机制,错误处理,在成千上万个线程I/O中,线程上下文切换是十分消耗CPU资源的)。
Overlapped I/O模型是OS为你传递数据,完成上下文切换,在处理完之后通知你。由程序中的处理,变为OS的处理。内部也是用线程处理的。
个人理解:线程a要产品拿到B国家做的加工,但是自己去成本太高,它就委托快递公司voerLapped 把商品寄到B国家的工厂,然后线程a就去做自己的事情了。
typedef struct _OVERLAPPED { // 通常被保留,当GetOverlappedResult()传回False // 并且GatLastError()并非传回ERROR_IO_PENDINO时,该状态置为系统定的状态。 DWORD Internal; // 通常被保留,当GetOverlappedResult()传回False时,为被传输数据的长度。 DWORD InternalHigh; // 指定文件的位置,从该位置传送数据,文件位置是相对文件开始处的字节偏移量。 // 调用 ReadFile或WriteFile函数之前调用进程设置这个成员, // 读写命名管道及通信设备时调用进程忽略这个成员; DWORD Offset; // 指定开始传送数据的字节偏移量的高位字, // 读写命名管道及通信设备时调用进程忽略这个成员; DWORD OffsetHigh; // 标识事件,数据传送完成时把它设为信号状态, // 调用ReadFile, WriteFile, ConnectNamedPipe TransactNamedPipe函数前,调用进程设置这个成员. HANDLE hEvent; } OVERLAPPED, *LPOVERLAPPED;
产生重叠IO的原因:
对于阻塞IO的读写操作都是需要阻塞等待IO完成的,大大的浪费用户的进程的时间片,降低了程序的性能。所以系统开个后门,悄悄地给你开个后门,开个线程去帮你请求IO,等到IO操作完成之后再通知你,你就可一再接着处理就好了,那么在IO完成之前你就可以放心的做其他的了。
重叠IO的重要数据结构:
WSAEVENT hEvent是连接完成事件和用户程序的桥梁,我们可以通过可爱的waitformultipleobjects和waitforsingleobject来接受通知,进而处理完成事件。
那么,IOCP又是怎么一肥事呢?
需要知道,重叠IO解放劳动力的同时,也是有代价的,如果1000个请求同时发生就需要系统内部开启1000个线程去处理IO,那么负载实在太大了,所以需要池化,为用户进程开线程池去优化IO请求咯。