调度、线程上下文以及IRQL

本文详细介绍了Windows内核中线程调度、线程上下文和中断请求级(IRQL)的概念。线程优先级从0到31,数值越高优先级越高。系统态线程并非总是高于用户态,高优先级用户线程可以抢占系统线程。调度过程中,系统会根据线程的时间配额和优先级进行切换。线程上下文包括硬件寄存器、堆栈和私有数据。驱动程序通常不直接创建线程,而是提供例程调用。IRQL分为多个级别,如PASSIVE_LEVEL、APC_LEVEL和DISPATCH_LEVEL,不同级别有不同的调度和中断规则。DPC和中断服务例程在处理设备中断和同步时起到关键作用。
摘要由CSDN通过智能技术生成

线程调度以及线程的上下文和当前的IRQL(中断请求级)对于每个处理器上面的驱动程序有很大的影响。而一个线程的调度优先级和处理器的当前IRQL能够决定一个运行的线程能否被中断或者抢占。在抢占式调度过程当中,系统能够利用同一个处理器上面的更高优先级的线程换掉当前正在运行的线程。一个线程上的抢占式调度使得处理器在一段时间内不能够可用。在中断线程的过程当中,系统强行要求当前线程临时的运行在一个更高中端级别上。线程中断的效果类似于一个强制性的过程调用。

线程作为执行的调度体,每一个线程都有调度优先级,这些优先级从031——数字越高就暗示这个线程有越高的优先级。每个线程都是按照一定的时间配额进行调度的。这个配额规定了每个线程在调度之前能够运行的最大的时间。时间配额根据系统的版本以及不同的处理器类型而有一定的差异,当然这个数字也能够被系统的管理员进行设置。

系统态的线程并不比用户态的线程更具特权,一个更高优先级的用户模式的线程能够抢占系统线程。1-15之间的线程优先级被称为动态特权。而线程优先级在16-31被称为实时特权。特权级0被用于页面清零线程——在内存管理当中用于清零空闲页面。每一个线程有一个基础优先级和一个当前的优先级。基础优先级一般继承自进程,而这个当前优先级则是线程在任意当前状态下的优先级。对于一个运行在用户线程上下文的内核模式驱动代码而言,基础优先级是最初清楚这个I/O操作的进程的用户进程的优先级,然而对于运行在系统线程上下文的内核驱动程序代码而言,基础优先级是系统线程的优先级。为了提高系统的吞吐量,系统有时候会调整线程的优先级。如果线程基础优先级在动态范围内,系统可以临时调整他的优先级,这使得他的当前优先级和基础优先级不一样。如果线程的基础优先级在实时范围内,他的当前优先级和基础优先级始终保持一致。另外,一个运行在动态优先级的线程决不能被调整为实时优先级。当线程完成I/O,被事件或者信号量唤醒的时候系统会提升他的优先级,或者在长期饥饿之后。涉及到GUI的线程或者用户前端进程总是在某些情况下会有优先级的提升。线程提升的幅度依赖于提升的原因。在WDM.h文件中定义了相应的提升幅度常数。线程调度的优先级不同于处理器上的中断请求级别(IRQL)

大多数驱动不创建线程而是提供一个例程调用,这些例程调用发生在应用程序或者系统组件创建的线程中。系统模式下面的软件开发成员在两种不同的情况下使用术语线程环境上下文CONTEXT结构体包含硬件寄存器以及堆栈和线程的私有数据。这个结构体的数据因为硬件平台的不同而不同。当windows进行线程调度的时候,他从线程的CONTEXT结构体当中获取用户模式的地址空间。从一个驱动开发者的理解,线程上下文具有更广泛的意义。对于一个驱动程序而言,线程上下文不仅仅包含CONTEXT当中的数值,同时还包含他们定义的操作环境,尤其是应用程序的调用权限。例如,一个驱动线程可能在用户模式下调用,然而他可能反过来在操作系统的环境上下文中调用一个内核级别的例程。驱动例程当中的线程上下文依赖于设备类型以及设备在设备堆栈当中的位置,以及系统当中的其他活动。

当一个IO请求排队的时候,那么就不知道驱动程序执行所在的线程上下文了。驱动请求操作会在请求出队的时候所被执行的任意线程环境当中。很少一部分驱动例程运行在系统线程的环境上下文当中,系统线程具备系统进程的地址空间和安全权限。利用IoXXXWorkItem进行请求排队的所有的请求都在系统线程当中被处理。系统包含三个workitems队列

1延迟工作队列。队列当中的请求执行的时候,有一个不同的、动态的线程优先级,驱动可以使用这个队列。

2关键段工作队列。这个队列的那个中的处理比延迟工作队列当中具备更高的优先级。

3超关键段工作队列。这个队列具备最高的优先级,但是这个队列是保留给系统使用的,驱动程序不能使用这个队列。

系统调用驱动程序的例程的时候保证驱动程序没有被清除,整个workitem处理过程所处的中断请求级别是PASSIVE_LEVEL。线程运行的级别只有两个PASSIVE_LEVELAPC_LEVEL。而实际上系统在这两个IRQL当中还包含了另外一层,利用一层IRQL实现了关键段代码。程序员利用KeEnterCriticalRegion进入这个IRQL,利用KeLeaveCriticalRegion回到PASSIVE_LEVEL。因此驱动代码在PASSIVE_LEVEL级别获取锁的时候必须保证不能被中断,如果被中断将使得不能访问设备。这种情况的解决办法之一是提高驱动代码本身的IRQL,或者进入到关键代码段。因为运行在比

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值