参考:http://www.myfaq.com.cn/A/2001-10-09/1180.html
OVERLAPPED(重叠):
WIN32中,用户需通过API接口访问硬件。开发者基于提供的接口进行开发,而把底层的访问交给Driver或内核.
WIN32中,设备的概念已经超过了Monitor,Printer等范围,可以包括文件,目录,串口,并口,管道以及控制
台等。当访问这些设备时,第一步就是打开这个设备,其中WIN32 API提供的是CreateFile.其中包括一些参数
表明了是否这个设备已经存在(dwCreationDisposition),是否以独占的方式(dwShareMode)打开等等.
由于设备的速度和CPU的速度存在很大的差异,怎么解决这个问题?Overlapped.
Overlapped意思就是当程序在等待设备操作的时候,可以继续往下做而不必阻塞到那个地方等待设备操作的返回,这
样就造成了程序运行和设备操作时间上的重叠。
程序怎么知道设备操作何时做完了返回?引入多线程的概念。多线程的同步问题:WIN32提供给我们的是WaitForSingleObject
和WaitForMultiObject两个函数,而WIN32中提供了一组专门用来同步的对象包括CCriticalSection(临界区),CEvent(事件),
CMutex(互斥量),CSemaphore(信号量)等,这其中绝大多数都属于内核对象(Kernel Object).这些对象都具备两种形态:有信号,
无信号。当我们使用Wait函数的时候,就可以根据信号的有无来使得程序是否阻塞在wait的地方。例如:我们调用一个函数
CEvent a;
WaitForSingleObject(a.m_hObject,INFINITE);//无限等待
的时候,如果a事件有信号 ,那么程序就往下跑,如果是无信号,那么程序就阻塞在当前位置,等待其变为有信号的。ss.SetEvent()
使它变为有信号的,而ss.ResetEvent()使得它变为无信号的,其他Mutex使得程序不能重复等等.
当我们想要一步的(OVERLAPPED)访问设备的时候,只要首先在CreateFile的时候用上(OVERLAPPED)标志,然后在读写操作
(对应的是WriteFile和ReadFile)的时候同样适用这个标志即可..
程序分析:
//1 以重叠方式接收指定字符,看函数是否读取成功
fReadStat = ReadFile(hCom,lpBlock,dwLength,&dwLenght,&osRead);
if(!fReadStat)
{
file://属重叠方式操作在后台进行的情况...
if(GetLastError() == ERROR_IO_PENDING)
//2
file://等待1s,若接收事件处于信号态,说明重叠方式操作完成,超时...
//3
if(WaitForSingleObject(osRead.hEvent,1000) == WAIT_TIMEOUT)
dwLength = 0;
}
else
dwLength = 0; //异常情况
这样当程序以异步的方式读取资料的时候,不管设备有没有操作完,程序会立即往下走而不用等待
其返回(如果是同步的那线程就会阻塞在这个地方).这样在2处就可以处理其他事情而不用管设备(这样
也就实现了时间上的重叠),直到需要等待3处资料进来后再做进一步的处理的时候,才会用上WairFor...
等待设备。
这样的操作提高了效率,使得程序和设备的配合协调了不少。