问题1:先看代码,代码涉及到3个event, 主线程中创建了3个evetn,同时同一个文件 采用异步io(重叠io方式大力,保存到3个缓冲区中)
为什么要同步,打开就打开呗,会出现什么问题你DWORD   nReadByte ;
BYTE   bBuf1[BUF_SIZE],bBuf2[BUF_SIZE],bBuf3[BUF_SIZE] ;
HANDLE  hEvent1 = CreateEvent ( NULL, FALSE, FALSE, NULL ) ; 
HANDLE  hEvent2 = CreateEvent ( NULL, FALSE, FALSE, NULL ) ;
HANDLE  hEvent3 = CreateEvent ( NULL, FALSE, FALSE, NULL ) ;
OVERLAPPED ov1 = { 0, 0, 0, 0, hEvent1 } ;  
OVERLAPPED ov2 = { 0, 0, 0, 0, hEvent2 } ;  
OVERLAPPED ov3 = { 0, 0, 0, 0, hEvent3 } ;  
HANDLE hFile = CreateFile ( ……, FILE_FLAG_OVERLAPPED, …… ) ;
ReadFile ( hFile, bBuf1, sizeof(bBuf1), &nReadByte, &ov1 ) ;
ReadFile ( hFile, bBuf2, sizeof(bBuf2), &nReadByte, &ov2 ) ;
ReadFile ( hFile, bBuf3, sizeof(bBuf3), &nReadByte, &ov3 ) ;
//此时3个I/O操作的同步对象分别为hEvent1,hEvent2,hEvent3
GetOverlappedResult ( hFile, &ov1, &nRead, TRUE ) ;问题2: (代码在问题1中) 是否可以如此替代,3个缓冲区,打开一次,到一个缓冲区中,然后拷贝缓冲区可以嘛?问题3:不是说打开一个大 的文件,采用 内存映射文件的方式吗?有什么区别呢?对于内存映射文件,我觉得很糊涂, 映射到内存中,多个进程可以使用这块内存,其中一个进程修改了,那么其他进程获得的内存也是被修改了。所谓共享机制。可以内存映射文件,为什么能打开大的文件呢?对于问题3,希望有完整代码,实际用途(代码来解释),我看了不少老帖子了, 对于问题3 ,大多是文字,原理的说明,不知道谁在项目中使用过?书本上不到十几行的代码,对我来说帮助不大,希望能看到实际用途,

解决方案 »

  1.   

    在这里你要明白的是:重叠的IO操作方式不是为了同步不同的IO操作,而是减少CPU在一些外部设备(如对磁盘文件的读写操作就是通过DMA方式来完成的)在进行IO操作的同时的等待。就拿磁盘文件读写操作来说吧,在阻塞式的IO操作之中,CPU向DMA发送一个文件读写请求,然后DMA被唤醒,进而执行CPU发送来的文件读写请求,由于一般IO操作速度远远比不上CPU的执行速度,DMA在进行IO操作的时候会耗掉大量的时间,而在IO操作完成之前CPU一直处于被阻塞的状态,直到DMA完成IO操作后通知CPU,这样CPU才能够执行以后的操作了,于是大量的CPU时间被浪费掉了,岂不可惜了。于是,为了解决CPU时间被严重浪费的这么一个问题,重叠的IO操作被引入进来。在重叠模式下面,CPU向DMA发送一个IO请求,这时候DMA被唤醒,进而执行CPU发送来的IO操作,此时,
    CPU不再是等待DMA完成IO操作,而是继续执行以后的任务,于是在DMA执行IO操作的同时,CPU也在执行任务,这样就实现了CPU与DMA的并行执行,CPU的时间被浪费的这一问题也得到了解决,于是一个问题就出现了,DMA执行完IO操作之后,CPU怎么知道呢,于是引入了事件对象,事件对象在DMA完成执行之前一直处于无信号状态,当DMA完成IO操作的执行的时候,事件对象将被置为有信号状态,通过事件等待与获取重叠操作的结果的调用,CPU得知已经完成的IO操作的信息,于是接着处理IO操作以后的操作了。
      

  2.   

    文件映射对象的原理与普通的文件IO之间有着很大的区别:
    在理解这么个问题之前,你得先明白虚拟地址空间这么一个概念,系统在启动一个进程时,将会给它分配一个4GB的虚拟地址空间(针对32位操作系统),这个地址空间不同于内存中的物理地址,CPU在执行指令的时候会将程序中的地址(程序中的地址一定是虚拟地址,如C语言中的指针,它指向的就是一虚拟地址,而不是物理地址),虚拟地址以页面的形式分配。CPU要执行应用程序,则该程序必须所在的页面必须映射到内存的帧中,帧的大小与页面的大小正好相等。
    普通的文件读写操作大约是这样的,先在虚拟地址空间中寻找一块空闲的可用的页面,并分配给进程,然后在内在之中分配一帧,并将页面映射到内存的帧中,此时,该页面才真正可读写。读操作就是将文件内容读到该页面上来,写操作就是将该页面上的内容写入到文件之中。注意,此时磁盘上的文件映像并没有映射到进程的虚拟地址空间上来。
    而文件映射对象的方式大约是这样的:在进程的地址空间中寻找一块空闲的页面,并分配给进程,然后将该页面映射到磁盘之中的打开的文件的映像之中,此时对该页面的读写操作就相当于对磁盘中的文件映射的读写操作了。Windows加载exe与dll文件映射都是采用这种方式。