当前位置:网站首页>深入理解.Net中的线程同步之构造模式(二)内核模式3.内核模式构造物Mutex
深入理解.Net中的线程同步之构造模式(二)内核模式3.内核模式构造物Mutex
2022-06-30 13:10:00 【小黄瓜要编程】
深入理解.Net中的线程同步之构造模式(二)内核模式构造
前言
Kernel-mode Constructs一般翻译为内核模式构造 ,
Constructs 即是一个名词也是一个动词,但是翻译为构造感觉有点像一个动词,个人感觉翻译为名词更好,毕竟是加了s的,就表示多个,动词显然不能表示多个啊,比如内核模式构造物,内核模式构造体。
环境说明
IDE:Visual Studio 2022
OS:Win10
.NET:.Net4.6.1
一、互斥体是什么?
互斥体mutex就是一个互斥的锁,和AutoResetEvent 事件锁类似。
只不过mutex比AutoResetEvent 事件锁多了一些额外的功能。mutex支持同一个线程多次获取一个锁,当然,多次获取后也需要多次释放才能让其他的线程可用,我们将这个多次获得锁的过程叫做递归锁,也叫可重入锁。但是使用mutex的时候,会频繁切换内核代码和托管代码,这样对程序的性能有一定的影响。可以用AutoRestEvent方法自己实现一个递归锁代替。
但是确实没有在编码中用到递归锁,也不能很好的想出一个场景。
难不成递归的时候用递归锁?好像也可以说的通喔!
二、代码编写
1.编写一个基于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的递归锁。
边栏推荐
- 单元测试效率优化:为什么要对程序进行测试?测试有什么好处?
- Directory related commands
- Resource realization applet opening traffic main tutorial
- Publicity of the fourth batch of shortlisted Enterprises - annual Top100 smart Internet supplier selection
- SQL考勤统计月报表
- rxjs Observable 两大类操作符简介
- 可觀測,才可靠:雲上自動化運維CloudOps系列沙龍 第一彈
- 损失函数:DIOU loss手写实现
- 智慧运维:基于 BIM 技术的可视化管理系统
- 发生QQ大规模盗号事件,暴露出什么网络安全问题?
猜你喜欢

【C】 In depth understanding of pointers and callback functions (Introduction to simulating qsort)

60 个神级 VS Code 插件!!

Observable, reliable: the first shot of cloudops series Salon of cloud automation operation and maintenance

发生QQ大规模盗号事件,暴露出什么网络安全问题?

SQL编程问题,测试用例不通过

Today's sleep quality record 80 points

SQL attendance statistics monthly report

Idea 2021.3 golang error: rning: undefined behavior version of delve is too old for go version 1.18

Matlab tips (22) matrix analysis -- stepwise regression

损失函数:DIOU loss手写实现
随机推荐
Dart 扩展特性
【科研数据处理】[实践]类别变量频数分析图表、数值变量分布图表与正态性检验(包含对数正态)
Directory related commands
[kali] Kali system, software update (with image source)
JS converts an array to a two-dimensional array based on the same value
一次 Keepalived 高可用的事故,让我重学了一遍它!
Step by step | help you easily submit Google play data security form
mysql拒绝访问、管理员身份打开的
Paper interpretation (AGC) attributed graph clustering via adaptive graph revolution
腾讯二面:@Bean 与 @Component 用在同一个类上,会怎么样?
Google Earth Engine(GEE)——将字符串的转化为数字并且应用于时间搜索( ee.Date.fromYMD)
SQL programming problem, test case failed
深度长文探讨Join运算的简化和提速
Embedded development: five C features that may no longer be prohibited
Introduction to two types of rxjs observable operators
2022-06-23 sail soft part formula and SQL generation (month and quarter retrieval)
Basic syntax of unity script (5) - vector
【刷题篇】供暖器
Clearing TinyMCE rich text cache in elementui
golang文件的写入、追加、读取、复制操作:bufio包的使用示例