本文主要总结如何使用“kernel object”来实现线程间的同步。与用户模式下的同步方法相比,内核对象同步的效率会相对要低一些(需要切换到内核模式下),但是,它可以跨进程使用,而且在编程上也更简单。
除了总结知识点,我还分析了内核对象同步实现的Queue.exe的示例代码,并与上一篇的Queue.exe进行了简单对比。最后,我将介绍微软提供的一种诊断死锁问题的手段:Wait Chain Tranversal。
一、Thread Synchronization with Kernel Object
二、Queue
本例应用内核对象同步,实现了一个(自身)线程安全的CQueue类。(为方便描述,我将上一篇的Queue称为Old Queue,这一章的Queue称为New Queue)。从功能上来看,它与Old Queue差不多,唯一不同的是:New Queue的Server端不再区分请求号的奇偶性。
从实现上来看New Queue:
1)它的底层也是通过预分配数组来实现。
2)它的成员函数比较简单,是标准的queue操作——入队和出队。
3)它的成员变量包含kernel object:一个mutex和一个semaphore。其中,mutex保护队列,包括入队和出队函数;而semaphore保护队列中的元素,修改队列中的元素时,需要先访问它。
4)需要注意的是,在出队函数中,该示例使用的是内存移动的方式,而不是元素拷贝。这样做可以提供效率。
// Shift the remaining elements down
MoveMemory(&m_pElements[0], &m_pElements[1],
sizeof(ELEMENT) * (m_nMaxElements - 1));
三、WCT -- Wait Chain Tranversal
多线程程序开发过程中,最难的是对多线程的调试和逻辑分析,特别是与锁相关的缺陷分析,比如:死锁和无限等待。为此,微乳提供了一套API,从系统层面来辅助开发者分析各个线程的运行状态(running or blocking)和线程与锁的等待关系,这就是:Wait Chain Tranversal。
关于WCT,我们可以搜索MSDN上的资料:
1) https://msdn.microsoft.com/en-us/library/windows/desktop/ms681622(v=vs.85).aspx
2) https://msdn.microsoft.com/en-us/library/cc308564.aspx
这两个系列的文章对WCT的原理和使用方法进行了相关介绍,并用示例进行了简单 演示。
此外,《Windows核心编程》也提供了Lockcop.exe和badlock.exe这一对示例来演示WCT。