windows驱动开发——锁、死锁、以及同步

本文详细介绍了Windows内核驱动开发中的各种同步机制,如互斥体、自旋锁、事件、快速互斥体、内核互斥体等,分析了它们的适用场景、IRQL级别以及使用注意事项。文章强调了锁的正确使用以避免死锁,并提出了防止死锁的编程原则。此外,还讨论了不同锁的特性,如自旋锁的繁忙等待、快速互斥体的限制以及如何在不同IRQL级别下选择合适的同步机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

表格中描述的是常用的同步机制,这些机制的相关描述以及他们在windows系统下面的实现。

同步方法

描述

Windows下的机制

Interlocked operations

提供原子的算术,逻辑,和列表操作,不仅是多线程安全的同时也是多处理器安全的

InterlockedXxx and ExInterlockedXxx routines

Mutexes

提供内存的互斥访问权限

Spin locks, fast mutexes, kernel mutexes, synchronization events

Shared/exclusive lock

运行一个线程专享写多个线程共享读

Executive resources

Counted semaphore

允许固定大小的获取权限

Semaphores

原子锁的实现需要处理器汇编的支持,因而可以在所有的IRQL级别上面使用。InterlockedXxx 例程能够运行在可换页数据当中。

一个互斥体保证共享资源的专有访问权限,任意能够保证互斥专有权限的锁都能被认为是互斥体。比如,自旋锁和同步事件都可以被认为是互斥体,因为当一个同步事件被唤醒的时候,仅有一个线程能够获取访问权限,同样自旋锁在并发条件下最多只能有一个线程能够被选中执行。互斥体的类型依赖于互斥体的使用环境,选择互斥体需要遵循下列规则:

1 互斥体可以运行的IRQL级别,也就是互斥体可以在哪一级IRQL当中获取和释放

获取互斥体是否会提升当前的IRQL?如果IRQL得到提升,那么原来的IRQL被保存在哪里?

3 是否互斥体的释放和获取必须在同一个线程环境上下文当中?

互斥体是否能够被递归获取,也就是说一个线程能否在不释放互斥体的条件下,再次获取该互斥体?

5 当一个持有互斥体的线程被终止而没有释放互斥体会出现什么情况?

互斥体类型

IRQL限制

递归和线程方面的细节

Interrupt spin lock

获取的时候提升IRQLDIRQL并且返回之前的IRQL给调用者

不能递归获取,获取和释放在同一个线程上下文

Spin lock

获取的时候提升IRQLDISPATCH_LEVEL并且返回之前的IRQL给调用者

不能递归获取,获取和释放在同一个线程上下文

Queued spin lock

获取的时候提升IRQLDISPATCH_LEVEL并且保存之前的IRQL在一个锁持有者句柄当中

不能递归获取,获取和释放在同一个线程上下文

Fast mutex

获取的时候提升IRQLAPC_LEVEL并且保存之前的IRQL到锁当中

不能递归获取,获取和释放在同一个线程上下文

Kernel mutex (a kernel dispatcher object)

在获取的时候进入代码互斥区域,在释放的时候离开代码互斥区域

可以递归获取,获取和释放在同一个线程上下文

Synchronization event (a kernel dispatcher object)

获取并不会改变IRQL,在小于等于APC_LEVEL级别等待,而在小于等于DISPATCH_LEVEL级别激发

不能递归获取,获取和释放不需要在同一个线程上下文

Unsafe fast mutex

获取的时候不改变IRQL并且在小于等于APC_LEVEL级别下面释放

不能递归获取,释放和获取在同一个线程上下文

共享互斥锁也被称为读写锁,允许一个线程进行专享的写操作,而其他的线程进行共享的读操作。计数信号量和互斥体一样,只不过可以出现多个线程同时获取信号量。

Windows同步机制

描述

IRQL限制

InterlockedXxx routines

在换页内存上执行原子的算术和逻辑运算

能够在任何IRQL当中获取

Spin locks

在非换页内存上提供专享的内存访问

在IRQL <= DISPATCH_LEVEL级别上获取

ExInterlockedXxx routines

执行算术、逻辑和列表控制的原子操作,不仅是多线程安全的同样也是多处理器安全的

在IRQL <= DISPATCH_LEVEL级别上访问 SList 历程; 其他历程可以在任意IRQL上面访问

Fast mutexes

在APC_LEVEL级别保护数据,同时防止线程被打断

在IRQL <= APC_LEVEL级别上获取

Executive resources

允许一个线程专享写而其他的线程共享读

在IRQL<=APC_LEVEL级别上获取

Kernel dispatcher objects (events, kernel mutexes, semaphores, timers, files, threads, processes)

在IRQL<=APC_LEVEL级别上提供不同形式的同步,能够和用户模式下的应用程序同步

在 IRQL <= APC_LEVEL下等待; 在IRQL <= DISPATCH_LEVEL下激发

Callback objects

在IRQL<=DISPATCH_LEVEL内核模式下面提供代码同步,能够用于驱动之间同步

在 IRQL <= DISPATCH_LEVEL被通知; 回调例程运行在激发线程的上下文当中,和激发线程的IRQL一样

自旋锁和它的名称所暗示的一样:当一个线程拥有自旋锁的时候,其他的线程在内存的某一个位置上通过忙等待自旋,直到锁是可用的。也就是说线程并不会阻塞,而是继续保持CPU的控制权,以防止执行相同或者更低IRQL中的代码。自旋锁是一个没有完全公开的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值