设备I/O OVERLAPPED模型分析

参考: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...

等待设备。

   这样的操作提高了效率,使得程序和设备的配合协调了不少。

 

你可能感兴趣的:(多线程,api,object,IO,File)