异步IO及APC

异步IO

异步IO是可以在IO操作时马上返回继续运行线程中后面的代码。在IO操作结束时可以根据IO操作的的返回结果分别处理。

自己操作异步IO返回

通过readfilewritefileapi,这些api既可以异步操作也可以同步操作。若要异步操作文件必须以异步的方式打开。主要是通过Synchronization Objects实现。

异步IO可在OVERLAPPED结构中指明同步原语的Synchronization Objects(针对同一个文件的每个异步IO指明一个),也可以不指明。

l  指明的话,可以先wait指定的Synchronization Objects,先WaitForSingleObject 然后GetOverlappedResult处理对应的一个异步IO操作。

l  如果不指明的话,只能GetOverlappedResult处理关于某一个文件的所有异步IO操作,因为没有Synchronization Objects自然不能WaitForSingleObject。而GetOverlappedResult只能指明某一文件的handle

指定completion routine处理IO返回

通过readfileexwritefileexapi,这些api只能异步操作。不是通过Synchronization Objects实现的,而是在参数中指定completion routine即操作完成是应该掉用的函数。

OVERLAPPED结构中不能指定Synchronization Objectshandle(因为不是需要通过用户指明事件处理,当然后台还

可能是根据事件来处理完成的。)。

由于不同的操作在参数中已经必须指明对应的completion routine。所以不同的操作有不同的处理。与上面的自己操作异步IO返回中指明同步原语的Synchronization Objects类似。

If the function succeeds, the calling thread has an asynchronous input/output (I/O) operation pending: the overlapped read operation from the file. When this I/O operation completes, and the calling thread is blocked in an alertable wait state, the system calls the function pointed to by lpCompletionRoutine, and the wait state completes with a return code of WAIT_IO_COMPLETION.

If the function succeeds, and the file reading operation completes, but the calling thread is not in an alertable wait state, the system queues the completion routine call, holding the call until the calling thread enters an alertable wait state. For information about alertable waits and overlapped input/output operations, see Synchronization and Overlapped Input and Output.

这里的的alertable waits等的不是readfileex的信号(前面提到这种方法根本没创建Synchronization Objects),而是其他信号,只是alertable的,这个alert才是来自readfileex操作结束,会中断wait先执行completion routineAPC

当前调用readfileex的线程已执行完毕、没有alertable waitsalertable waits已经等到了它所等的信号。这些情况下completion routine不会被执行么。

貌似这种就是APC

GetOverlappedResult是否也可用于这种异步。

APC

一个线程有一个对应的APC queque,里面放的是待执行的APC。可以手动通过QueueUserAPC手动加入,或者是SetWaitableTimer的时间到了时,会加指定的APCAPC queque中。

SetWaitableTimer

1.         CreateWaitableTimer创建一个timer T,这个timer从概念上讲与T相关的参数只有定下一次什么时候signale,没有循环的时间。

2.         第一次时间和循环时间由SetWaitableTimer定,在线程A调用SetWaitableTimer之后,SetWaitableTimer马上把T的时间设为第一次的等待时间,然后把T加入到内核timer queue

3.         T的时间到的时候把与T关联的completion routine 加入到调用SetWaitableTimer的线程T对应的APC queue,并把T从内核timer queue中移去。

4.         这之后SetWaitableTimer根据循环时间间隔把T的下一次signale时间定为循环的时间,并像先前那样把T加入内核timer queue

5.         而线程的APC queue则等到对应的线程A处于alertable wait state(比如A调用WaitForSingleObjectEx参数设为alertable并阻塞在那里时,按APC ququeAPC函数 FIFO的顺序供线程调用。会由操作系统对这个函数创建一个子线程调用,由于MSDN中提到An asynchronous procedure call (APC) is a function that executes asynchronously in the context of a particular thread所以看上去应该与线程A创建这个子线程效果相同,意思是这个APC运行的线程的父线程是线程A

Timer Queues

CreateTimerQueue创建一个TimerQueue

CreateTimerQueueTimer在一个现有的TimerQueue上加入一个Timer

Time的时间到后就会自动执行对应的completion routine

这种方法不要求调用CreateTimerQueueTimer线程处于alertable wait state调用completion routine要求线程必须处于运行状态,所以调用线程最好还是wait在那里,还有不知道是否必须不能是alertable wait

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值