Kernel-mode Constructs一般翻译为内核模式构造 ,
Constructs 即是一个名词也是一个动词,但是翻译为构造感觉有点像一个动词,个人感觉翻译为名词更好,毕竟是加了s的,就表示多个,动词显然不能表示多个啊,比如内核模式构造物,内核模式构造体。
环境说明
IDE:Visual Studio 2022
OS:Win10
.NET:.Net4.6.1
互斥体mutex就是一个互斥的锁,和AutoResetEvent 事件锁类似。
只不过mutex比AutoResetEvent 事件锁多了一些额外的功能。mutex支持同一个线程多次获取一个锁,当然,多次获取后也需要多次释放才能让其他的线程可用,我们将这个多次获得锁的过程叫做递归锁,也叫可重入锁。但是使用mutex的时候,会频繁切换内核代码和托管代码,这样对程序的性能有一定的影响。可以用AutoRestEvent方法自己实现一个递归锁代替。
但是确实没有在编码中用到递归锁,也不能很好的想出一个场景。
难不成递归的时候用递归锁?好像也可以说的通喔!
主要是用来理解一下递归锁的实现,相对于普通的事件锁,主要增加了2个变量来实现,一个是记录获得锁的线程ID变量,一个是记录获取锁次数的变量。
代码如下(示例):
internal sealed class RecursiveAutoResetEvent : IDisposable
{
private AutoResetEvent m_lock = new AutoResetEvent(true);
private Int32 m_owningThreadId = 0;
private Int32 m_recursionCount = 0;
public void Enter()
{
// Obtain the calling thread's unique Int32 ID
// 获取唯一的线程ID
Int32 currentThreadId = Thread.CurrentThread.ManagedThreadId;
// If the calling thread owns the lock, increment the recursion count
//
if (m_owningThreadId == currentThreadId)
{
m_recursionCount++;
return;
}
// The calling thread doesn't own the lock, wait for it
m_lock.WaitOne();
// The calling now owns the lock, initialize the owning thread ID & recursion count
m_owningThreadId = currentThreadId;
m_recursionCount--;
}
public void Leave()
{
// If the calling thread doesn't own the lock, we have an error
if (m_owningThreadId != Thread.CurrentThread.ManagedThreadId)
throw new InvalidOperationException();
// Subtract 1 from the recursion count
if (--m_recursionCount == 0)
{
// If the recursion count is 0, then no thread owns the lock
m_owningThreadId = 0;
m_lock.Set(); // Wake up 1 waiting thread (if any)
}
}
public void Dispose() { m_lock.Dispose(); }
}
递归锁我们使用的情况很少,而且mutex的递归锁存在多次从托管代码转到内核代码,性能理论上要低于AutoResetEvent的递归锁。