Overlapped模型深入分析(原理篇)

  
Overlapped I/O模型深入分析
简述:
     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的处理。内部也是用线程处理的。
 
Overlapped数据结构:
typedef struct _OVERLAPPED {
    DWORD   Internal;      通常被保留,当 GetOverlappedResult()传回False并且GatLastError()并非传回ERROR_IO_PENDINO时,该状态置为系统定的状态。
DWORD    InternalHigh;  通常被保留,当 GetOverlappedResult()传回False时,为
                        被传输数据的长度。
DWORD    Offset;        指定文件的位置,从该位置传送数据,文件位置是相对文件开始
处的字节偏移量。调用 ReadFile或WriteFile函数之前调用进
程设置这个成员,读写命名管道及通信设备时调用进程忽略这
个成员;
DWORD    OffsetHigh;    指定开始传送数据的字节偏移量的高位字,读写命名管道及通
信设备时调用进程忽略这个成员;
HANDLE hEvent;          标识事件,数据传送完成时把它设为信号状态,调用ReadFile
                          WriteFile   ConnectNamedPipe   TransactNamedPipe 函数
前,调用进程设置这个成员. 相关函数 
CreateEvent  ResetEvent   GetOverlappedResult  
WaitForSingleObject   CWinThread   GetLastError   
} OVERLAPPED, *LPOVERLAPPED;
二个重要功能:
1. 标识每个正在 overlapped 的操作。
2. 程序和系统之间提供了共享区域。参数可以在区域内双向传递。
 
OVERLAPPED和数据缓冲区释放问题 :
在请求时,不能释放,只有在 I/O请求完成之后,才可以释放。如果发出多个overlapped请求,每个overlapped读写操作,都必须包含文件位置(socket),另外,如果有多个磁盘,I/O执行次序无法保证。(每个overlapped都是独立的请求操作)。
 
 
内核对象(hand)实现:
例子:用 overlapped模型读一个磁盘文件内容。
   1.把设备句柄看作同步对象, ReadFile将设备句柄设为无信号。ReadFile 异步I/O字节位置必须在OVERLAPPED结构中指定。
   2.完成 I/O,设置信息状态。为有信号。
   3. WaitForSingleObject或WaitForMultipleObject判断
或者异步设备调用 GetOverLappedResult函数。
 
int main()
{
    BOOL rc;
    HANDLE hFile;
    DWORD numread;
    OVERLAPPED overlap;
    char buf[READ_SIZE];
    char szPath[MAX_PATH];
    CheckOsVersion();
 
    GetWindowsDirectory(szPath, sizeof(szPath));
    strcat(szPath, "//WINHLP32.EXE");
    hFile = CreateFile( szPath,
                    GENERIC_READ,
                    FILE_SHARE_READ|FILE_SHARE_WRITE,
                    NULL,
                    OPEN_EXISTING,
                    FILE_FLAG_OVERLAPPED,
                    NULL
                );
    if (hFile == INVALID_HANDLE_VALUE)
    {
        printf("Could not open %s/n", szPath);
        return -1;
    }
 
    memset(&overlap, 0, sizeof(overlap));
    overlap.Offset = 1500;
 
    rc = ReadFile(
                hFile,
                buf,
                READ_SIZE,
                &numread,
                &overlap
            );
    printf("Issued read request/n");
    if (rc)
    {
        printf("Request was returned immediately/n");
    }
    else
    {
        if (GetLastError() == ERROR_IO_PENDING)
        {
            printf("Request queued, waiting.../n");
            WaitForSingleObject(hFile, INFINITE);
            printf("Request completed./n");
            rc = GetOverlappedResult(
                                    hFile,
                                    &overlap,
                                    &numread,
                                    FALSE
                                );
            printf("Result was %d/n", rc);
        }
        else
        {
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值