互斥变量对象包含一个使用计数,一个线程ID,一个递归计数。它的行为和关键代码段一样,互斥变量是内核对象,关键段是用户模式下的同步对象。在这种情况下,等待资源的线程不得不由用户模式切换到内核模式,加大消耗,速度变慢。
互斥变量对象包含的一个线程ID是指当前拥有互斥变量对象的线程,这也是唯一一个会记住等待成功的线程ID的内核对象,当该ID为0时,互斥变量变为有信号状态。
在等待线程中,系统将该线程与互斥变量对象包含的线程ID对比,如果不一致则继续等待,如果一致则等待成功获得资源的支配权。
当线程调用ReleaseMutex的时候,函数会检查当前线程ID是否与互斥对象内部保存的线程ID不一致,函数将不执行任何动作并返回FALSE,调用GetLastError返回ERROR_NOT_OWNER。如果拥有互斥变量对象的线程在ReleaseMutex之前终止,互斥变量就无法得到释放,互斥变量将被“遗弃”。此时,系统会自动将互斥变量内部拥有的线程ID置为0,它的递归计数也将为0,并将互斥对象“公平”的分配给一个正在等待的线程。
这和以前一样,唯一不同的是,等待函数返回的结果将为WAIT_ABANDONED,而不是正常的WAIT_OBJECT_0。这种情况很尴尬也很危险,刚刚获得互斥变量的线程并不知道现在的资源处于什么状态,它可能已经完全被破坏了。
这也是个很好的例子,告诫我们为什么不要直接用TerminateThread函数。