1.写C++程序时,会出现一些情况,做此记录
举例:
类似读取文件
先CreateFile,接着再ReadFile或者WriteFile
情况1:
如果CreateFile时,
参数DWORD dwFlagsAndAttributes, 该参数代表文件属性,该参数没有设置为FILE_FLAG_OVERLAPPED(允许对文件进行重叠操作)
那么在ReadFile时,就需要等读完数据后(数据的长度是自己指定的),才会返回。
假设在WriteFile时,需要一次性写入很多数据,那么需要在数据完全写完,才会返回。
就会有程序卡住的感觉,
情况2:
如果CreateFile时,
参数DWORD dwFlagsAndAttributes, ,该参数设置为FILE_FLAG_OVERLAPPED
那么在ReadFile和WriteFile时,最后一个参数LPOVERLAPPED lpOverlapped。
该参数百度定义如下:
//如文件打开时(CreateFile)指定了FILE_FLAG_OVERLAPPED,那么必须,用这个参数引用一个特殊的结构。该结构定义了一次异步读取操作。否则,应将这个参数设为NULL
也就是CreateFile和ReadFile都需要注意,在CreateFile时参数调用FILE_FLAG_OVERLAPPED,在ReadFile时,最后一个参数定义为 OVERLAPPED m_osRead。
那么调用后就会立刻返回,不需要等到数据读取或者保存结束。
好处1:可以不用等到数据读取或者保存结束。
好处2:可以同时发出多个ReadFile或者WriteFile
这就是所谓的重叠I/O
因为已经返回了,不知道什么时候写完或者读完,所以可以在其他地方去
WaitForSingleObject或者WaitForMultipleObjects去等待Windows的内核对象
等到了信息就说明之前的操作已经结束了
可以继续调用GetOverlappedResult去获取结果
总结:
1.对于I/O的读写操作,需要在CreateFile时设置参数为FILE_FLAG_OVERLAPPED
2.接着再ReadFile和WriteFile时,会直接返回结果
3.在其他地方调用WaitForSingleObject或者WaitForMultipleObjects去等待之前ReadFile和WriteFile操作有没有结束
4.如果结束了调用GetOverlappedResult去获取结果
原理
同步:对于Windows内核而言,当CPU运行过程中收到一个I/O请求(类似读写文件操作),
系统会产生一个中断,去让CPU执行该操作,执行完毕后再产生一个中断,去运行之前的程序。
异步:对于Windows内核而言,当CPU运行过程中收到一个I/O请求(类似读写文件操作),
系统会产生一个线程,该线程去处理读写的操作,
与此同时,CPU还在运行之前的程序
代码举例: