APC -- Asynchronous Procedure Call 异步过程调用
异步过程调用(APC -- Asynchronous Procedure Call )是一种与常用的和简单的同步对象不同的一种同步机制。
我们在我们线程里使用基本的同步对象如MUTEX去通知其它线程,它应该停下来等我们完成之后你再继续。APCs使用了一种不同的策略,
因此可能要求应用程序不同的设计。一个APC是一种回调函数类型。与普通的函数指针在调用上有些类似。我们能够在需要通知其它任务一
些事情时可以调用这样的函数。这个任务将在回调函数内部处理这个事件,而不是等待该事件并在通知后继续工作,实际的工作写在了回调
函数里。普通回调函数将在调用者上下文中执行该函数。例如,线程A调用回调函数,则回调函数运行在线程A的上下文中,同时线程B也正
在做一些事情。想一下,一个线程正在重画窗体,而另外一个线程有一些新的信息要显示在窗口上。
这里的APC机制解决了同步问题,而不需要MUTEX或者Event来包含共享资源。当一个线程使用APC时它告诉系统让其他线程调用该回调函
数时运行在回调函数自己上下文中。换句话说,任务A告诉任务B去执行一个函数。任务B将不中断它自己的工作区执行这个动作。相反它将
完成所有的事情,然后去执行该回调函数。这种同步假设了回调函数将在任务完成之后才被调用,所以它已经完成了资源的使用。看一下画
图的这个例子,它完成了画整个窗体后才开始更新新数据。
APC的机制将等待目标任务完成它的所有工作。因为今天的应用程序大部分时间是在等待下一个系统事件,它假设当任务完成了所有工作,
然后进入一个等待状态知道下一系统事件到来。操作系统(同步库)将偷走这个任务的事件等到该任务进入等待状态时,并跳到了回调函数
的地址上。当函数返回时,该任务将回来在原始的代码或函数上继续等待。
使用同步机制要求在操作期间不等待,所以我们在处理资源时不需要使用MUTEX或事件。
APC是一个在特定线程中执行的函数。当一个APC压入APC队列时,系统将引发一个软中断。接下来该线程将被调度,并运行该APC函数。
APC有2中类型:内核模式的APC和用户模式的APC;内核模式APC由系统产生,而用户模式的由应用程序产生。
每一个线程都有自己的APC队列。可以使用QueueUserAPC函数把一个APC函数压入APC队列中。APC排队就是请求线程调用APC函数。
当用户模式的APC压入线程APC队列后,该线程并不直接调用APC函数,除非该线程是处于可通知状态。当一个线程调用SleepEx,
SignalObjectAndWait、MsgWaitForMultipleObjectsEx,WaitForMultipleObjectsEx或者WaitForSingleObjectEx函数时,它才进入可
通知状态。如果在APC压入队列之前,线程进入可通知状态,则该APC函数将不被执行,因为此时该线程并不是处于可通知状态。然而,该
APC函数仍然在队列中,所以在下次调用可通知状态函数时,它将被调用。
ReadFileEx,SetWaitableTime,SetWaitableTimerEx和WriteFileEx函数是使用一个作为完成通知回调机制的APC来实现的。
如果你正在使用一个线程池,那么注意该APC并不能和其它信号机制一起工作。因为系统控制了线程池的生命周期,可能在通知之前该线程
被终止了。应该使用可等待对象比如CreateThreadpoolTimer创建的定时器,而不是基于APC的通知机制--如SetWaitableTimer或
SetWaitableTimerEx的参数pfnCompletionRoutine。对于I/O,使用一个用CreateThreadpoolIo创建的I/O完成对象或者一个基于事件的
OVERLAPPED结构体传递到SetThreadpoolWait函数中。
当一个发起I/O请求时,一个结构体被分配来表示该请求。该结构体称为I/O请求包(IRP -- I/O request packet)。同步I/O,线程将构造
这个IRP,并发送到设备栈,等待内核完成IRP。异步I/O,线程构造IRP并发送个设备栈。设备栈可能立即完成IRP,也可能返回一个
pending状态,告诉线程正在处理中。这时,该IRP仍然关联着线程,所以该线程终止时或者调用CancelIo时该IRP将被取消。同时,线程在
处理设备栈的IRP时能够继续执行其它任务。
有以下几种方法知道IRP已经完成:
当IRP完成时将用操作结果更新overlapped结构体,所以线程能够轮询操作是否完成。
当IRP完成时将触发overlapped结构体中的event时,所以当操作完成时,线程能同步并处理。
把IRP压入线程未决的APC时,当线程处于可通知状态时将执行APC函数并返回等待操作带有指示它执行一个或多个APC函数的状态。
把IRP压入一个I/O完成端口时,它将被等待该完成端口的下一个线程执行。
等待IO完成端口的线程并不等待可通知状态。因此,如果这些线程发起了被作为APC设置为完成的IRP到线程时,这些IPC完成不能及时地发
生;它们将在线程从IO完成端口获得请求并碰巧进入了可通知状态时才发生。
http://asyncop.com/link.aspx?apc
http://msdn.microsoft.com/en-us/library/windows/desktop/ms681951%28v=vs.85%29.aspx
APC -- Asynchronous Procedure Call 异步过程调用的更多相关文章
- WINDOWS硬件通知应用程序的常方法(五种方式:异步过程调用APC,事件方式VxD,消息方式,异步I/O方式,事件方式WDM)
摘要:在目前流行的Windows操作系统中,设备驱动程序是操纵硬件的最底层软件接口.为了共享在设备驱动程序设计过程中的经验,给出设备驱动程序通知应用程序的5种方法,详细说明每种方法的原理和实现过程,并 ...
- APC (Asynchronous Procedure Call)
系统创建新线程时,会同时创建与这个线程相关联的队列,即异步过程调用(APC)的队列. 一些异步操作可以通过加入APC来实现,比如我现在学习的IO请求/完成. BOOL ReadFileEx( HAND ...
- 通过异步程序调用(APC)实现的定时功能
定时器是一个在特定时间或者规则间隔被激发的内核对象.结合定时器的异步程序调用可以允许回调函数在任何定时器被激发的时候执行.本文的例子代码显示了如何实现. 使用本定时器时,你需要把常量_WIN32_WI ...
- win32多线程-异步过程调用(asynchronous Procedure Calls, APCs)
使用overlapped I/O并搭配event对象-----win32多线程-异步(asynchronous) I/O事例,会产生两个基础性问题. 第一个问题是,使用WaitForMultipleO ...
- RPC-远程过程调用协议
远程过程调用协议 同义词 RPC一般指远程过程调用协议 RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要 ...
- ARM过程调用标准---APCS简单介绍
介绍 APCS,ARM 过程调用标准(ARM Procedure Call Standard),提供了紧凑的编写例程的一种机制,定义的例程能够与其它例程交织在一起.最显著的一点是对这些例程来自哪里没有 ...
- Java同步和异步过程中消息语言国际化处理策略
在Java后端做消息内容的语言国际化处理时可以通过Spring中MessageSource接口的来实现,但是MessageSource接口需要用到Locale对象, 而Locale类又是根据前端传过来 ...
- 进程内部异步事件调用组件Async-Event
项目坐标:https://github.com/cncduLee/async-event async-event 进程内部异步事件调用组件 解决什么问题: 加速服务处理效率.提供进程级别的事件发布和异 ...
- 从汇编角度分析C语言的过程调用
➠更多技术干货请戳:听云博客 基本术语定义 1.系统栈(system stack)是一个内存区,位于进程地址空间的末端. 2.在将数据压栈时,栈是自顶向下增长的,该内存区用于函数的局部变量提供内存.它 ...
随机推荐
- iOS开发——新特性篇&swift新特性(__nullable和__nonnull)
swift新特性(__nullable和__nonnull) 最近在看老师写代码的时候经常遇到两个陌生的关键字,但是当我在我的电脑上敲得时候就是敲不出,后来才知道这是为了swift与OC混编的时候产生 ...
- python selenium自动化(二)自动化注册流程
需求:使用python selenium来自动测试一个网站注册的流程. 假设这个网站的注册流程分为三步,需要提供比较多的信息: 在这个流程里面,需要用户填入信息.在下拉菜单中选择.选择单选的radio ...
- ResolveClientUrl("~/Styles/Site.cs")%>
区别: <%=ResolveClientUrl("~/Styles/Site.cs")%> 和 <%=ResolveUrl("~/Styles/Site ...
- maven学习(二)
为了兼容之前基于ant构建的项目发布包结构,在基于maven做构建的时候,需要自定义打包方式. maven的maven-assembly-plugin插件支持任意格式的打包,比如:dir,zip等形式 ...
- debian的备份与还原
不管是windows还是linux 备份都很重要 因为配好一个系统是要花很多时间的 出了问题的话 有备份直接还原就可以了 windows下有ghost 那么linux下呢?Linux可以在系统正在运行 ...
- C#_模拟webAp_POST-GET-PUT-DELETE
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.N ...
- 探索 ConcurrentHashMap 高并发性的实现机制--转
ConcurrentHashMap 是 Java concurrent 包的重要成员.本文将结合 Java 内存模型,来分析 ConcurrentHashMap 的 JDK 源代码.通过本文,读者将了 ...
- win7 debian 双系统修改引导项顺序
转载:http://jingyan.baidu.com/article/72ee561aa1d123e16138df81.html 问题描述: 个人在宿舍使用的比较多的是Window 7,而它的启动项 ...
- [Java] Eclipse注释模板设置详解
设置注释模板的入口: Window->Preference->Java->Code Style->Code Template 然后展开Comments节点就是所有需设置注释的元 ...
- React Redux Sever Rendering实战
# React Redux Sever Rendering(Isomorphic JavaScript) ![React Redux Sever Rendering(Isomorphic)入门](ht ...