参考资料:
1. 《Windows Internals》
3. Lock指令前缀
4. Lock指令前缀(二)
知识点:
● Interlocked Operations:最简单的同步机制,基于硬件对安全多处理器整数操作的支持,包括:InterlockedIncrement、interlockedDecrement、InterlockedExchange和InterlockedCompareExchange。比如interlockedDecrement函数,会通过x86指令前缀来锁住多处理的总线(如,地址总线),防止修改某一内存空间。
● Spinlocks:与mutex比较类似,不同之处在于它的使用者往往保持时间比较短,且不会进入休眠状态。在使用的时候,可以设置尝试次数;如果超时,就放弃本次时间片。
两个限制:① 被保护的资源必须被快速访问且不会被其它代码复杂的访问。
② 临界区代码不能被分页在内存外,不能引用可分页的数据,不能调用外部例程(包括系统服务)和不能产生中断和异常。
图1 Spinlock使用实例
● Queued Spinlocks:为增减扩展性的特殊类型spinlock。工作原理:当某一个处理器想获取一个当前已被拥有的QS,它把它的标识符放到与该Spinlock相关的队列中去。让Spinlock被释放的时候,其拥有进程会将lock传递到队列中的第一个进程。 同时,一个进程会检查它前面进程的per-processosr标志位,以判断是否轮到自己了。Wndows定义了很多全局的QS。
图2 全局Queued Spinlocks
● 多处理器环境中,内核外的可执行程序同样需要同步对全局数据结构的访问。比如,内存管理器唯一的页帧数据库。
● 当spinlock不适用时的几种同步机制:①Kernel dispatcher objects、②Fast mutexes and guarded mutexes、③Pushlocks和④Executive resources。
● Windows支持的几种用户模式下的锁原子操作:①Condition variables、②Slim Reader-Writer Locks、③Run-once intialization和④Critical sections。
● Kernel Dispatcher Object:内核会以内核对象的形式提供额外的同步机制给执行程序,这些内核对象的集合即是Dispatcher Objects。线程通过对待内核调度对象的句柄来实现同步。内核会将该线程置于等待状态。任何时刻,内核调度对象都有两种状态:signaled状态和nonsignaled状态(具体对象的signaled状态定义是不同的)。
表1 5种内核调度对象
Object | Data Type | Description |
---|---|---|
Event | KEVENT | Blocks a thread until some other thread detects that an event has occurred |
Semaphore | KSEMAPHORE | Used instead of an event when an arbitrary number of wait calls can be satisfied |
Mutex | KMUTEX | Excludes other threads from executing a particular section of code |
Timer | KTIMER | Delays execution of a thread for some period of time |
Thread | KTHREAD | Blocks one thread until another thread terminates |
● Fast mutexes又被称为executive mutexes,被广泛使用在设备驱动中,通常提供比mutex对象更好的性能,尽管它也是建立在Dispatcher Event Object上的。它只有在该fast mutex被竞争的情况下才执行wait操作,而标准mutex总是会尝试得到该互斥量。
● Guarded mutexes同fast mutex很相似,只不过是它使用了另一种同步对象(KGATE)而已。
● Executive resource是一种支持共享和互斥访问的同步机制。它常用文件系统驱动程序。
● Pushlock是另一种基于Gate对象的优化同步机制。Pushlock可以以共享或互斥的模式被获得。