zoukankan      html  css  js  c++  java
  • Overlapped I/O 学习 流沙

    1、Overlapped I/O 的含义

    Overlapped I/O 是WIN32的一项技术,可以让操作系统进行I/O操作而不阻塞的程序执行,并且I/O操作完成时通知程序。

    事实上Overlapped I/O操作系统最终是以线程的方式实现。

    2、使用Overlapped I/O

    Windows中通过CreateFile来打开各种资源。如:文件、串口、并口、Name pipes、Console等等。

    1: HANDLE WINAPI CreateFile(
    2: __in LPCTSTR lpFileName, //资源名称
    3: __in DWORD dwDesiredAccess, //存取模式
    4: __in DWORD dwShareMode, //共享模式
    5: __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes, //指向安全属性结构
    6: __in DWORD dwCreationDisposition,//如何产生
    7: __in DWORD dwFlagsAndAttributes, //资源属性
    8: __in_opt HANDLE hTemplateFile //零时文件,将拥有全部属性的拷贝
    9: );
    其第6个参数指定为FILE_FLAG_OVERLAPPED,就是准备使用overlapped的方式构造或打开文件;

    如果采用 overlapped,那么ReadFile()、WriteFile()的第5个参数必须提供一个指针,指向一个OVERLAPPED结构。 OVERLAPPED用于记录了当前正在操作的文件一些相关信息。

    1: BOOL WINAPI ReadFile(
    2: __in HANDLE hFile, //资源句柄
    3: __out LPVOID lpBuffer, //输出缓冲区指针
    4: __in DWORD nNumberOfBytesToRead, //输出字节数
    5: __out_opt LPDWORD lpNumberOfBytesRead, //实际读取的字节个数的地址
    6: __inout_opt LPOVERLAPPED lpOverlapped //指向Overlapped info
    7: );
    8: BOOL WINAPI WriteFile(
    9: __in HANDLE hFile, //资源指针
    10: __in LPCVOID lpBuffer, //写入数据缓冲区
    11: __in DWORD nNumberOfBytesToWrite, //写入字节数
    12: __out_opt LPDWORD lpNumberOfBytesWritten,//实际写入字节数
    13: __inout_opt LPOVERLAPPED lpOverlapped //指向Overlapped info
    14: );
    Overlapped 结构

    1: typedef struct _OVERLAPPED
    2: {
    3: ULONG_PTR Internal;
    4: ULONG_PTR InternalHigh;
    5: union {
    6: struct {
    7: DWORD Offset;
    8: DWORD OffsetHigh;
    9: };
    10: PVOID Pointer;
    11: };
    12: HANDLE hEvent;
    13: } OVERLAPPED, *LPOVERLAPPED;
    结构字段含义

    Internal:保留为系统使用。当GetOverlappedResult返回False时,且用GetLastError返回不是ERROR_IO_PENDING时,该字段为一个视系统而定的状态。

    InternalHigh:保留为系统使用。当GetOverlappedResult为TRUE时,该字段为被传输数据长度。

    Offset:当目标设备为文件时该字段有效,其他时候必须为0;表示文件中被传输数据的偏移位置(从文件头开始计算)。

    OffsetHigh:64位文件偏移中的高32位。当目标设备为文件时有效。其他时候必须为0。

    Pointer:保留为系统时候。

    hEvent:一个手动复位的事件句柄,当Overlapper I/O完成时,被触发。

    1: BOOL WINAPI GetOverlappedResult(
    2: __in HANDLE hFile, //资源句柄
    3: __in LPOVERLAPPED lpOverlapped, //Overlapped指针
    4: __out LPDWORD lpNumberOfBytesTransferred, //真正被传输的字节数
    5: __in BOOL bWait //是否需要等等I/O完成
    6: );
    示例:

    1: #include <Windows.h>
    2: #include <stdio.h>
    3:
    4: int main()
    5: {
    6: BOOL bRet;
    7: HANDLE hFile = NULL;
    8: OVERLAPPED overlapped;
    9: LPCTSTR szPath = TEXT("H:\\Resource.rar");
    10: unsigned char buf[1024*100];
    11: DWORD nRead = 0;
    12: /*以OVERLAPPED方式打开一个文件*/
    13: hFile = ::CreateFile(szPath,
    14: GENERIC_ALL,
    15: FILE_SHARE_READ | FILE_SHARE_WRITE,
    16: NULL,
    17: OPEN_EXISTING,
    18: FILE_FLAG_OVERLAPPED,
    19: NULL
    20: );
    21: if (hFile != INVALID_HANDLE_VALUE)
    22: {
    23: memset(&overlapped,0x00,sizeof(overlapped));
    24: memset(buf,0x00,sizeof(buf));
    25: overlapped.Offset = 0;
    26:
    27: bRet = ::ReadFile(hFile,
    28: buf,
    29: 1024*10,
    30: &nRead,
    31: &overlapped
    32: );
    33: if (bRet)
    34: {
    35: for (DWORD i = 0;i < nRead;i++)
    36: {
    37: printf("%02X ",buf[i]);
    38: if ((i + 1) % 16 == 0)
    39: {
    40: printf("\n");
    41: }
    42: }
    43: printf("\n");
    44: }
    45: else
    46: {
    47: DWORD err = GetLastError();
    48: if (err == ERROR_IO_PENDING)
    49: {
    50: bRet = GetOverlappedResult(hFile,&overlapped,&nRead,TRUE);
    51: if (bRet)
    52: {
    53: for (DWORD i = 0;i < nRead;i++)
    54: {
    55: printf("%02X ",buf[i]);
    56: }
    57: printf("\n");
    58: }
    59: else
    60: {
    61: printf("Error Code : %d\n",GetLastError());
    62: }
    63: }
    64: else
    65: {
    66: printf("Error Code : %d\n",err);


  • 相关阅读:
    【Luogu P5515】[MtOI2019]灵梦的计算器
    简易的命令行入门教程
    8个接私活的网站,只要你有码,那“我”就有钱
    单表查询必会13条
    「Django」rest_framework学习系列-路由
    Linux下将时间修改为当地时间(通过ntpdate服务)
    iptables拒绝发起大量请求(针对单IP地址)
    .webp格式win7无法显示缩略图
    永久修改/etc/proc下的项的配置文件
    通过vsftpd实现虚拟用户登录,不同的用户登录不同的目录,使用不同的权限
  • 原文地址:https://www.cnblogs.com/darkdance/p/2275996.html
Copyright © 2011-2022 走看看