b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

ccriticalsection 调用 2次_递归 2次调用_layoutsubviews 调用2次(6)

电脑杂谈  发布时间:2019-07-13 03:09:05  来源:网络整理

APC机制使操作系统能在特定线程上下文中执行一个函数。APC的异步含义是,系统可以有效地中断目标线程以执行一个外部例程。APC的动作有点类似于硬件中断使处理器从任何当前代码突然跳到ISR的情形,它是不可预见的。

现在我们要定义wndproc函数.原因是createglwindow函数会调用wndproc函数但是wndproc函数的实现在createglwindow函数后面.在c语言中,如果要在一个函数里面调用一个实现代码在其后面的函数的话,必须在该函数之前先声明要调用函数的原型.所以这里先声明wndproc函数,这样createglwindow函数就能调用它了.。由于是用createremotethread函数远程执行getmodulehandle函数.所以无法直接从getmodulehandle函数得到返回值(也就是dll句柄).在此必在waitforsingleobject函数之后用getexitcodethread函数来获取线程的退出代码.如果线程正确返回.该退出代码就是线程函数(getmodulehandle)的返回值然后再用同样的方法用createremotethread远程创建线程调用freelibrary函数来卸载该dll。这对比多进程的fork()来说,从代码上看会更直观,只是我们必须要分清楚调用一个函数,和新建一个线程去调用一个函数,之间的差别:新建线程去调用函数,这个操作会很快的结束,并不会依序去执行那个函数,而是代表着,那个函数中的代码,可能和线程调用之后的代码,交替的执行。

如果系统唤醒线程去提交一个APC,则使该线程阻塞的等待原语函数将返回特殊状态值STATUS_KERNEL_APC或STATUS_USER_APC。

APC与I/O请求

内核使用APC概念有多种目的。由于本书仅讨论驱动程序的编写,所以我仅解释APC与执行I/O操作之间的关系。在某些场合,当用户模式程序在一个句柄上执行同步的ReadFile操作时,Win32子系统就调用一个名为NtReadFile(尽管未公开,但已经被广泛了解)的内核模式例程。该函数创建并提交一个IRP到适当的设备驱动程序,而驱动程序通常返回STATUS_PENDING以指出操作未完成。NtReadFile然后向ReadFile也返回这个状态代码,于是ReadFile调用NtWaitForSingleObject函数,这将使应用程序在那个用户模式句柄指向的文件对象上等待。NtWaitForSingleObject接着调用KeWaitForSingleObject以执行一个非警惕的用户模式的等待,在文件对象内部的一个事件对象上等待。

当设备驱动程序最后完成了读操作时,它调用IoCompleteRequest函数,该函数接下来排队一个特殊的内核模式APC。该APC例程然后调用KeSetEvent函数使文件对象进入信号态,因此应用程序被释放并得以继续执行。有时,I/O请求被完成后还需要执行一些其它任务,如缓冲区复制,而这些操作又必须发生在请求线程的地址上下文中,因此会需要其它种类的APC。如果请求线程不处于警惕性的等待状态,则需要内核模式APC。如果在提交APC时线程并不适合运行,则需要特殊的APC。实际上,APC例程就是用于唤醒线程的机制。

(2)该函数的调用并不能由驱动自己调用,只有当内核认为是时候让驱动处理对设备的读写操作时,它才调用这个函数。c应用程序调用操作系统的函数时,首先需要编写一个使用int指令调用操作系统函数的函数,c程序通过调用这个汇编函数达到调用操作系统函数的目的。 api包含了几百个应用程序调用的函数,这些函数执行所有必须的与操作系统相关的操作,如内存分配、向屏幕输出和创建窗口等,用户的程序通过调用api接口同windows打交道,无论什么样的应用程序,其底层最终都是通过调用各种api函数来实现各种功能的。

如何指定Alertable和WaitMode参数

现在你已经有足够的背景资料了解等待原语中的Alertable和WaitMode参数。作为一个通用规则,你绝不要写同步响应用户模式请求的代码,仅能为确定的I/O控制请求这样做。一般说来,最好挂起长耗时的操作(从派遣例程中返回STATUS_PENDING代码)而以异步方式完成。再有,你不要一上来就调用等待原语。线程阻塞仅适合设备驱动程序中的某几个地方使用。下面几段介绍了这几个地方。

内核线程 有时,当你的设备需要周期性循检时,你需要创建自己的内核模式线程。

处理PnP请求 我将在第六章中讨论如何处理PnP管理器发送给你的I/O请求。有几个PnP请求需要你在驱动程序这边同步处理。换句话说,你把这些请求传递到低级驱动程序并等待它们完成。你将调用KeWaitForSingleObject函数并在内核模式中等待,这是由于PnP管理器是在内核模式线程的上下文中调用你的驱动程序。另外,如果你需要执行作为处理PnP请求一部分的辅助请求时,例如,与USB设备通信,你应在内核模式中等待。

处理其它I/O请求 当你正在处理其它种类的I/O请求时,并且你知道正运行在一个非任意线程上下文中时,那么你在行动前必须仔细考虑,如果你确信那个线程可以被阻塞,你应该在调用者所处于的处理器模式中等待。在多数情况下,你可以利用IRP中的RequestorMode域。此外,你还可以调用ExGetPreviousMode来确定前一个处理器模式。如果你在用户模式中等待,并允许用户程序调用QueueUserAPC提前终止等待,你应该执行一个警惕性等待。

我最后要提到的情况是,在用户模式中等待并要允许用户模式APC打断,你应使用警惕性等待。

底线是:使用非警惕性等待,除非你知道不这样做的原因。

下面是MFC中的同步对象及其用途,仅供参考

前言:一块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源,比如多个线程访问同一个对象、同一个变量、同一个文件和同一个方法等。(1)dll程序被映射到宿主进程的地址空间中,它能够共享宿主进程的资源,并根据宿主进程在目标主机的级别非法访问相应的系统资源。在某些环境中(例如:多个进程访问单个套接字), 引发 sigio 的东西在进程对信号作出反应时可能已经消失了. 如果这样的话, 进程应该再次等待, 因为 linux 稍后会重发此信号.。

类CEvent的对象代表一个“事件”:一种同步对象,用于一个线程通知另一个线程某事件发生。事件通常用于线程想知道何时执行其任务。例如,复制数据到某文件的线程需要被通知数据何时准备好。用CEvent对象可以通知复制线程数据已经有效,这样线程就可以尽快地执行其任务。CEvent对象有两种类型:手动和自动。手动CEvent对象将停留在SetEvent或ResetEvent设置的状态,除非你再次设置它。自动CEvent对象在一个线程释放后自动回到非信号态(无效状态)。

类CMutex的对象代表一个“互斥”:一种同步对象,可以使一个线程排斥性地访问某个资源。互斥可以用于一次仅允许一个线程访问的资源。例如,向链表添加一个接点的过程就是一次只允许一个线程执行。通过使用CMutex对象控制链表,一次只能有一个线程获得链表的访问权。

类CCriticalSection的对象代表一个“关键段”:一种同步对象,代表一次只允许一个线程访问的资源或代码片段。例如,向链表添加一个节点。使用CCriticalSection对象控制的链表一次只允许一个线程访问该链表。如果着重于执行速度并且被保护资源不跨进程使用,也可以用关键段代替互斥。

其它内核模式同步要素

Windows 2000内核为同步线程执行和保护共享对象访问提供了一些额外的方法。在这一节中,我们将讨论快速互斥(fast mutex)对象,通过对无竞争情况的优化处理,它可以提供比普通内核互斥对象更快的执行性能。我还将描述一种名称中含有“互锁(Interlocked)”术语的支持函数。这些函数都执行某种公用操作,例如增加或减少一个整数的值,从链表中插入或删除一个表项,这些操作都是以原子方式执行,从而可以避免多任务或多处理器的干扰。

参照内核互斥,表4-6列出了快速互斥的优点和缺点。有利的一面,快速互斥在没有实际竞争的情况下可以快速获取和释放。不利的一面,你不能递归获取一个快速互斥对象。即如果你拥有快速互斥对象你就不能发出APC,这意味着你将处于APC_LEVEL或更高的IRQL,在这一级上,线程优先级将失效,但你的代码将不受干扰地执行,除非有硬件中断发生。

表4-6. 内核互斥和快速互斥的比较

内核互斥快速互斥

可以被单线程递归获取(系统为其维护一个请求计数器)

不能被递归获取

速度慢

速度快

所有者只能收到“特殊的”内核APC

所有者不能收到任何APC

所有者不能被换出内存

(2) sched_rr(轮循)策略是基本相同的,不同之处在于:如果有一个sched_rr策略的线程执行了超过一个固定的时期(时间片间隔)没有阻塞,而另外的sched_rr或schbd_fipo策略的相同优先级的线程准备好时,运行的线程将被抢占以便准备好的线程可以执行。策略的线程执行了超过一个固定的时期(时间片间隔)没有阻塞,而另外的sched_rr或schbd_fipo策略的相同优先级的线程准备好时,运行的线程将被抢占以便准备好的线程可以执行。我们考虑一种很坏的情况,如果有若干相同优先级的线程等待执行,然而最早执行的线程无终止或者阻塞动作,那么其他线程是无法执行的,除非当前线程调用如pthread_yield之类的函数,所以在使用sched_fifo的时候要小心处理相同级别线程的动作。

可以是多对象等待的一部分

不能作为KeWaitForMultipleObjects的参数使用


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-112548-6.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...