I/O接口_overlapping

I/O接口_overlappingOverlappedI/O是Windows系统上的AsynchronousI/Oimplementation。啥叫asynchronousI/O?借用LinuxManpage中对AIO的

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

Overlapped I/O是Windows系统上的Asynchronous I/O implementation。啥叫asynchronous I/O ?借用Linux Man page中对AIO的介绍:

The POSIX asynchronous I/O (AIO) interface allows applications to initiate one or more I/O operations that are performed asynchronously (i.e., in the background). The application can elect to be notified of completion of the I/O operation in a variety of ways: by delivery of a signal, by instantiation of a thread, or no notification at all.

AIO让应用发起一个操作请求,让这个请求被异步地执行。应用可以选择在操作完成时被通知到或者不被通知。 

typedef struct _OVERLAPPED {
  ULONG_PTR Internal;
  ULONG_PTR InternalHigh;
  union {
    struct {
      DWORD Offset;
      DWORD OffsetHigh;
    };
    PVOID  Pointer;
  };
  HANDLE    hEvent;
} OVERLAPPED, *LPOVERLAPPED;

 

关于这个数据结构的详细介绍可以参考:http://msdn.microsoft.com/en-us/library/windows/desktop/ms684342(v=vs.85).aspx。 概括来说,Internal,InternalHigh都是内部使用的,不建议直接使用;Offset + OffsetHigh用于有offset概念的handle;Pointer是保留给系统使用的;hEvent指向一个event,当操作完成后,这个event会被系统设置成signalled状态。

看起来,这个数据结构本身并没有提供很多信息,那如何使用这个数据结构呢?

  

OVERLAPPED使用之一:内核对象(handle)

无论是对一个Socket或者文件或者其他什么对象操作,总有一个handle来指向这个对象。当对这个对象发出操作请求后,过一段时间就可以使用该handle和Overlapped对象进行查询,之前的那个请求是否完成。下面是一个例子:

用overlapped模型读一个磁盘文件内容。

   1.把设备句柄看作同步对象,ReadFile将设备句柄设为无信号。ReadFile 异步I/O字节位置必须在OVERLAPPED结构中指定。

   2.完成I/O,设置信息状态。为有信号。

   3.WaitForSingleObject或WaitForMultipleObject判断或者异步设备调用GetOverLappedResult函数。

 

#include <Windows.h>


#define READ_SIZE 1024

int main()

{

    BOOL rc;

    HANDLE hFile;

    DWORD numread;

    OVERLAPPED overlap;

    
char buf[READ_SIZE];

    
char szPath[MAX_PATH];

    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

        {

            printf(

Error reading file\n
);

        }

    }

    CloseHandle(hFile);

    
return EXIT_SUCCESS;

}

 

OVERLAPPED使用之二: 事件通知

每一个异步操作,都有一个OVERLAPPED的instance与之相关联,因此,当之前提交的异步操作完成后,可以使用OVERLAPPED中的hEvent来获取通知。写完示例程序可以贴出来。

 

Limitation:

1. WaitForMultipleObjects最多可以等待MAXIMUM_WAIT_OBJECTS(64)个对象,当提交的请求比较多(>64)时,就没法同时等。

2. 只能使用一个file handle;

 

OVERLAPPED使用之三: COMPLETION ROUTINE

另外一种方法是注册一个回调函数,在一个Overlapped I/O完成之后,系统调用该回调函数。OS在有信号状态下(设备句柄),才会调用回调函数(可能有很多APCS等待处理了),传给它完成I/O请求的错误码,传输字节数和Overlapped结构的地址。看看OVERLAPPED的定义,这个回调函数是没法跟OVERLAPPED进行关联了,那在哪里关联呢?答案是在每次请求时关联,比如WSARecv, ReadFileEx, WSASend 等函数都有一个参数为LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,这就是call back函数可以注册的地方。写完示例程序可以贴出来。

可以注意到,在这种方式时,并不需要每个IO request创建一个OVERLAPPED实例,因为没有用到OVERLAPPED里的任何信息。大家共享一个就可以了。

 

Limitation:

1. 只有发出overlapped IO请求的线程才可以提供callback函数,每个callback都会创建一个新线程,那么就是每个request都要创建线程,用完销毁,开销太大。

2. 只能使用一个file handle;

 

OVERLAPPED使用之四: IOCP

IOCP是在OVERLAPPED IO基础上的扩展。功能更加强大。OVERLAPPED IO会创建IO request 队列,当有异步请求时,就把请求放到这个队列里,系统会从队列中取请求并处理;IOCP主要是接近请求完成后通知的问题,IOCP是又创建了一个完成队列,当OVERLAPPED IO中的request 队列中有request被完成时,就放到IOCP的完成队列中,App的GetQueuedCompletionStatus从完成队列中取一个completion packet,进行处理。

所以,IOCP是以OVERLAPPED IO为基础的完成通知机制,对OVERLAPPED数据结构中的信息被不真正关心。但是必须要有一个OVERLAPPED的instance。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/167132.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux ntp时钟服务器地址_Linux时间同步+国内常用的NTP服务器地址【NTP时间同步服务器】…

    linux ntp时钟服务器地址_Linux时间同步+国内常用的NTP服务器地址【NTP时间同步服务器】…210.72.145.44(国家授时中心服务器IP地址)133.100.11.8日本福冈大学time-a.nist.gov129.6.15.28NIST,Gaithersburg,Marylandtime-b.nist.gov129.6.15.29NIST,Gaithersburg,Marylandtime-a.timefreq.bldrdoc.gov132.163.4.1…

    2022年5月28日
    60
  • spring3.2 定时器 SchedulerFactoryBean 注入错误[通俗易懂]

    spring3.2 定时器 SchedulerFactoryBean 注入错误[通俗易懂]异常信息[org.springframework.scheduling.quartz.SchedulerFactoryBean]forproperty’scheduler’;nestedexceptionisjava.lang.IllegalArgumentException:Cannotconvertvalueoftype[org.quartz.impl.Std

    2022年5月10日
    31
  • 强化学习 — MCTS

    强化学习 — MCTS目录Simulation-BasedSearchMCSearchMCTS上线置信区间算法UCT棋类游戏MCTS搜索Simulation-BasedSearch基于仿真的搜索包含两点:一个是simulation,其次是search。simulation是基于强化学习model进行采样,得到样本数据。但这不是基于和环境交互获得的真实数据。search则是为了利用样本结果来帮我们计算应该采用什么动作,以实现长期利益最大化要理解什么是Simulation-BasedSearch,首先要明白什么是for

    2022年6月18日
    28
  • b4什么意思_f0是什么车

    b4什么意思_f0是什么车AndroidEagleEyeAnXposedandadbibasedmodulewhichiscapableofhookingbothJavaandNativemethodstargetingAndroidOS.Relatedinformationofthehookedmethodswillbeloggedastheoutput.Us…

    2022年8月16日
    4
  • 【转载】热电偶和热电阻的区别

    一、热电阻和热电偶的测量原理1、热电偶的测量原理热电偶工作原理是基于赛贝克(seeback)效应,即两种不同成分的导体两端连接成回路,如两连接端温度不同,则在回路内产生热电流的物理现象。热电偶由两根不同导线(热电极)组成,它们的一端是互相焊接的,形成热电偶的测量端(也称工作端)。将它插入待测温度的介质中;而热电偶的另一端(参比端或自由端)则与显示仪表相连。如果热电偶的测量端与参比端存在…

    2022年4月7日
    45
  • ipconfig配置ip地址(为什么输入ipconfig没有用)

     IP可以分为PublicIP和PrivateIP,出现这种规划的原因在于IPv4所能表示的IP太少而电脑太多以至于不够用,然而只有PublicIP才能直接连接上网络,所以对于那些公司,学校,政府机构等场所,就可以集中使用私有的IP进行管理,而大家可以共用一个IP去连接上公网,这样,就省下了许多宝贵的PublicIP。你有没有发现,你每次使用ipconfig查到的地址,要么就是172….

    2022年4月15日
    84

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号