Delphi驱动开发研究之内核同步对象—线程与定时器

本篇及下篇教程我们将讲述内核同步对象。同步是一个涉及面非常广的主题,系统提供了多种同步对象,因此两篇文章也仅能让您对其有个大致的了解。
10.1 同步对象
迄今为止,我们都不需要独占访问某个数据,因为我们仅有一个线程在工作。当有两个或多个线程都需要访问同一个资源时,就需要引入同步机制,否则此资源的状态就无法预知了。比如当两个线程同时访问(在一个多处理器的系统中这种情况很常见)一个保存在共亨内存中的变量。常见的解决方法就是后面的线程等待前一个线程完成数据访问。
为解决此类问题,操作系统提供了一些同步对象的机制:事件(Event)、互斥(Mutex)--在内核中被称为突变体(Mutant)、信号灯(Semaphore)等等。这些同步机制在用户模式下也存在,而且使用方法也大同小异。
所有的同步对象结构的第一个字段均为一个DISPATCHER_HEADER结构用以描述此对象所期望的操作。下面是本章将要用到的两个结构:定时器对象(又叫watchdog)和线程对象。

_KTIMER = packed record
  Header: DISPATCHER_HEADER;
  ……
end;

KTHREAD = packed record
  Header: DISPATCHER_HEADER;
  . . . 
KTHREAD ENDS 
end;

从逻辑上讲,每个对象与其同胞对象均有不同之处,这个很容易理解,在这里我也不打算讲太多。在这里假设您使用过用户模式下的相关同步机制,我仅强调一下每个同步对象均有两种状态:释放(信号态)或者忙碌(非信号态)。
内核模式与用户模式在同步的管理上并无大的差异,但还是有几个地方需要注意:首先也是最重要的一点就是同步对象的IRQL要比DISPATCH_LEVLE低,也就是说执行在高于或等于DISPATCH_LEVEL级上的代码不能阻塞线程。这个规则表明你只能在DriverEntry函数、AddDevice函数,或驱动程序的分派函数中阻塞当前线程。因为这些函数都执行在PASSIVE_LEVEL级上。没有必要在DriverEntry或AddDevice函数中阻塞当前线程,因为这些函数的工作仅仅是初始化一些数据结构。其次在内核模式下是通过指向同步对象的指针访问该对象的,而在用户模式下则是通过对象句柄访问。
调用KeWaitForSingleObject或KeWaitForMultipleObjects函数可以使代码(以及背景线程)在一个或多个同步对象上等待,等待它们进入信号态。内核为初始化和控制这些对象的状态提供了例程。
10.2 教程源码
unit TimerWorks;

interface

uses
  nt_status, ntoskrnl, hal, native, fcall, macros;

function _DriverEntry(pDriverObject:PDRIVER_OBJECT;
                              pusRegistryPath:PUNICODE_STRING): NTSTATUS; stdcall;

implementation

var
  g_pkThread: PVOID;  {PTR KTHREAD}
  g_fStop: Boolean;
  g_usDeviceName, g_usSymbolicLinkName: UNICODE_STRING;

function ThreadProc(StartContext: PVOID): NTSTATUS;
var
  dwCounter: DWORD;
  pkThread: PVOID;  {PKTHREAD}
  _kTimer: KTIMER;
  liDueTime: LARGE_INTEGER;
  iPriority: KPRIORITY;
begin
  dwCounter := 0;
  DbgPrint(#13#10'TimerWorks: Entering ThreadProc'#13#10);

  DbgPrint('TimerWorks: IRQL = %d'#13#10, KeGetCurrentIrql);
  pkThread := KeGetCurrentThread;
  iPriority := KeQueryPriorityThread(pkThread);
  DbgPrint('TimerWorks: Thread Priority = %d'#13#10, iPriority);
  Inc(iPriority, 2);
  KeSetPriorityThread(pkTh
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值