深入理解.Net中的线程同步之构造模式(二)内核模式构造
前言
Kernel-mode Constructs一般翻译为内核模式构造 ,
Constructs 即是一个名词也是一个动词,但是翻译为构造感觉有点像一个动词,个人感觉翻译为名词更好,毕竟是加了s的,就表示多个,动词显然不能表示多个啊,比如内核模式构造物,内核模式构造体。
环境说明
IDE:Visual Studio 2022
OS:Win10
.NET:.Net4.6.1
一、内核模式的优点
我们前面3个小节简单的过了一个内核构造物的三个常见的构造物,现在我们就来说说为什么要使用内核构造物?内核构造物的优点?
内核模式的一个很重要的优点是可以进行跨进程线程同步(我们限制我们的应用只能运行一个程序)
相比用户模式的自旋,内核模式构造物会进行线程的阻塞
可以在托管线程和本地线程之间相互同步
可以基于EventWaitHandleSecurity进行一定的线程访问权限控制
二、代码编写
1.基于EventWaitHandle改造一个简单的锁
代码如下(示例):
public sealed class EventLock : IDisposable
{
private readonly EventWaitHandle m_available;
public EventLock()
{
m_available = new EventWaitHandle(true,EventResetMode.AutoReset,"testEvent"); // Initially free
}
public void Enter()
{
Int32 currentThreadId = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine($"线程ID:{currentThreadId},{DateTime.Now},阻塞等待开始");
// Block in kernel until resource available
m_available.WaitOne();
Console.WriteLine($"线程ID:{currentThreadId},{DateTime.Now},阻塞等待完成");
}
public void Leave()
{
// Let another thread access the resource
m_available.Set();
}
public void Dispose()
{
m_available.Dispose();
}
}
2.测试InterProcessLockTest跨线程锁的效果
代码如下(示例):
internal class Program
{
static void Main(string[] args)
{
new InterProcessLockTest().TestStart();
Console.ReadLine();
}
}
public class InterProcessLockTest
{
public void TestStart()
{
Console.WriteLine(" InterProcessLockTest TestStart Start !");
IntObj intObj = new IntObj();
EventLock eventLock = new EventLock();
eventLock.Enter();
Console.WriteLine($"get lock,{ DateTime.Now}");
Thread.Sleep(1000*30);
Console.WriteLine($"wait 30s,{ DateTime.Now}");
Console.WriteLine(" InterProcessLockTest TestStart END !");
}
}
我们先编辑完成,进入debug目录下直接运行控制台程序,可以看见如下
然后再启动visual studio调试界面
我们可以分析代码得知,获取锁后,我们不会释放锁,这个时候我们重新开启一个程序(可以视作一个进程),这时,进程获取不到锁,因为在另外一个进程中没有锁释放。
这个就是跨进程同步