线程、同步与锁——Mutex想说爱你不容易

除了Lock()、Monitor之外,我们最长用的就是Mutex了,但是玩不好Mutex就总会造成死锁或者AbandonedMutexException(我就玩的不怎么好,在并发性访问测试的时候总是遇到关于Mutex的问题,各位线虫见笑了,不过还是把我遇到的一些问题和总结拿出来和大家分享,有误的地方还往指正。

还是先举一个简单的例子,来说明一下这个东西:

 

   public class ThreadMutex

    {


        
public void Test()

        {

            Thread t1 
= new Thread(Thread1);

            Thread t2 
= new Thread(Thread2);

            t1.Start();

            t2.Start();

        }

        
public void Thread1()

        {

            Mutex m 
= new Mutex(false"test");

            
bool b2 = m.WaitOne();

            Console.WriteLine(
"Thread1 get the mutex : " + b2);

            Thread.Sleep(
10000);

            m.ReleaseMutex();

        }

        
public void Thread2()

        {

            Mutex m 
= new Mutex(false"test");

            
bool b2 = m.WaitOne();

            Console.WriteLine(
"Thread2 get the mutex : " + b2);

            Thread.Sleep(
1000);

            m.ReleaseMutex();

            

        }

}

恩,Thread1中Mutex.WaitOne()后,就想到与Thread1拿到了Mutex所有权,这时Thread2得到了同样的Mutex,然后Mutex.WaitOne(),也想拿到Mutex的所有权,这时就必须等待了。这里只需要两点就能明白什么是Mutex了:

1.   Mutex是一个令牌,当一个线程拿到这个令牌时运行,另外想拿到令牌的线程就必须等待,直到拿到令牌的线程释放令牌。没有所有权的线程是无法释放令牌的。

2.   Mutex(false,”string”)中的string是令牌的关键,或者可以叫令牌名,因为Mutex是跨进程的,整个系统中只会有唯一的令牌存在所以,也就是说你在一个应用程序中的一个线程中得到了Mutex的所有权,那在另外一个线程中的另外的线程想得到他就必须要等待。

 

要弄清楚Mutex就还需要弄清楚两个很重要的问题:

1.那就是Mutex是调用的Win32 的API 

HANDLE CreateMutex(

   LPSECURITY_ATTRIBUTES lpMutexAttributes,

   BOOL bInitialOwner,

   LPCTSTR lpName

);

这就是他为什么能跨进程访问的原因,正是由于它使用P/Invoke,他的效率问题就凸现出来,明显不如Monitor之类的快,用的时候还需多多斟酌。

 

下面放一个Mutex的简单实现,看看Mutex在.net下是如何实现的。

ContractedBlock.gif 

2.Mutex的生命周期,这个问题让我郁闷了很久,因为不太了解Mutex的机制,使得我也没法弄清楚到底能活多长时间,这也是AbandonedMutexException经常会出现的原因。还是先来看一段程序:

 

  public class ThreadMutex

    {

        
public void Test()

        {

            Thread t1 
= new Thread(Thread1);

            Thread t2 
= new Thread(Thread2);

            t1.Start();

            t2.Start();

        }

        
public void Thread1()

        {

            Mutex m 
= new Mutex(false"test");

            
bool b2 = m.WaitOne();

            Console.WriteLine(
"Thread1 get the mutex : " + b2);

        }

        
public void Thread2()

        {

            Thread.Sleep(
10);//保证Thread1执行完

            Mutex m 
= new Mutex(false"test");

            
bool b2=m.WaitOne();

            Console.WriteLine(b2);

            m.ReleaseMutex();

        }

}

在Thread2中的WaitOne()方法就会报错了,AbandonedMutexException,原因就是Thread1拿到了Mutex后没有释放,Thread1就结束了,这样Mutex成了被抛弃的地孩子了,呵呵。但是如果垃圾收集了,就不一样咯。代码稍微修改了一下:

 

  public class ThreadMutex

    {

        
public void Test()

        {

            Thread t1 
= new Thread(Thread1);

            Thread t2 
= new Thread(Thread2);

            t1.Start();

            t2.Start();

        }

        
public void Thread1()

        {

            Mutex m 
= new Mutex(false"test");

            
bool b2 = m.WaitOne();

            Console.WriteLine(
"Thread1 get the mutex : " + b2);

        }

        
public void Thread2()

        {

            Thread.Sleep(
10);//保证Thread1执行完

            GC.Collect();

            GC.WaitForPendingFinalizers();

            
bool b1;

            Mutex m 
= new Mutex(false"test",out b1);

            Console.WriteLine(b1);

            
bool b2=m.WaitOne();

            Console.WriteLine(b2);

            m.ReleaseMutex();

            

        }

    }

结果是:

Thread1 get the mutex : True

True

True

Thread2里面的Mutex是新创建的,呵呵,这里面的玄妙自己体会吧。

 

最后要说一下的是Mutex的访问和window访问文件的机制基本上是一样的,window访问对象和访问文件使用的是同样的安全机制(虽然我还没看懂)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/464960.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32F4 串口DMA

串口DMA方式收发 笔者使用的是STM32F407VET6,共包含6路串口,页尾处程序已将全部串口的DMA收发配置完成,本文仅以串口1为例进行讲解。(查看代码可直接跳至第二节或页尾处下载) 1 STM32F4 DMA 简介 DMA,全称为…

由马化腾谈“微博修改功能”,看什么是优秀的产品经理

我仔细阅读过马化腾的的简历,他是一位技术出身的企业家。也是腾讯最大的产品经理,大家都知道产品经理的对产品的重要性那是不言而喻的,而产品是公司的灵魂。 今天早上起床,看到马化腾先生更新的微博。有位网络公司的CTO建议腾讯微博加一个修改…

flask 必知必会

在局域网中让其它电脑访问我的网站 from flask import Flaskapp Flask(__name__)app.route(/) def hello_world():return hello worldif __name__ __main__:app.run(debugTrue,host0.0.0.0,port9000) 转载于:https://www.cnblogs.com/wuheng-123/p/9665004.html

KEIL编译生成bin文件,并输出内存使用情况

一、STM32CubeMX生成的代码输出bin文件 输出bin文件: Run#1框填入的是:fromelf.exe空格–bin空格-o空格"$LL.bin"空格"#L"。“–bin”是两根英文短杆。 fromelf.exe --bin -o "$LL.bin" "#L"编译的时候&#x…

建议去华为

提问:老师,您好!我现在手里有两个offer,正在艰难抉择中,一个是小米的相机图像调校工程师(camera tuning),工作地在深圳,工资是12k*14,还有大概700元的餐补&am…

快学好这个去给学妹修热水器

作者:晓宇,排版:晓宇微信公众号:芯片之家(ID:chiphome-dy)2021年6月25号晚上9点,中国南方某一线城市,小张正在看着前阵子新出的电影误杀2,窗外,疲…

Win10系统添加 Win10 LTSC2019闹钟

1、本文主要针对没有windows闹钟的情况。 2、下载Win10 LTSC 2019闹钟应用,并解压: http://www.winwin7.com/soft/xtbd-2695.html 链接:https://pan.baidu.com/s/1S_g6XUIezeF8_Q0rJ09cBQ 提取码:68gs 3、搜索Windows Powershell&…

iPhone开发笔记[1/50]:初学iPhone上用Quartz 2D画图

参考了An iOS 4 iPhone Graphics Drawing Tutorial using Quartz 2D这篇文章,用了30分钟在iPhone上画出了一条直线,核心代码全在drawRect这个方法中: -(void)drawRect:(CGRect)rect { CGContextRef context UIGraphicsGetCurrentContext(); C…

昨晚上跟读者闲聊

昨天发了一篇华为小米的求职文章,今天一个知识星球的朋友找我聊天,也是关于择业的问题。本来是聊找工作的,然后聊着聊着就聊到了生活的一些事情。我平时比较关注微信信息,有重要能回复就会回复,但是,也不喜…

上次作业的升级版

好好好 211606375 牛振乾 211606351 曾茜 一、预估与实际 PSP2.1Personal Software Process Stages预估耗时(分钟)实际耗时(分钟)Planning计划• Estimate• 估计这个任务需要多少时间4040Development开发9001000• Analysis• 需…

学习vim的正确姿势!

有很多种方法可以去学习Vim:vimtutor就是一个很棒的教程,另外还有help拥有您所想的所有参考信息。链接:https://github.com/wsdjeg/Learn-Vim_zh_cn但是在日常使用中,对于绝大部分用户的需求而言,vimtutor讲得太浅不能满足需要&am…

什么是自由软件?

来源 | www.gnu.org编排 | strongerHuang可能你认为免费软件,就是自由软件,那么你肯定错了,下面来听听专家怎么描述自由软件的。strongerHuang1自由软件定义开源(Open source)是另外一回事:它有基于不同价值…

毕业设计| STM32F103全彩FFT音乐频谱+LED年历闹钟显示

大家好,我是写代码的篮球球痴,今天在后台看到有人想找毕业设计的点子。然后我今天刚好看到一个不错的点子,给大家分享看今天分享的毕设是来自点-凡自制的FTF音乐频谱制作,先来看展示效果:——视频出处:B站点…

VScode 开发stm32无法识别uint32_t,uint16_t,uint8_t问题

1、添加头文件#include “stdint.h”。 2、在c_cpp_properties.json文件中添加__CC_ARM即可。如下图:

毕业这几年的嵌入式开发之路

大家好,我是写代码的篮球球痴今天分享一篇文章,这篇文章的主人公总结了他这些年来的嵌入式之路,希望对大家的职业规划有所帮助。在毕业即失业的年代,来看一位朋友是如何玩转嵌入式开发的,献给迷惘的你。出师不利本科毕…

修改Win10 alt+F4默认选项为关机

1、winr打开路径计算机\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced,当前目录下新建DWORD(32位)文件,命名为“Start_PowerButtonAction”。设置值为2(16进制)。 2、重启电脑。altF4默认为“关…

p1968

我觉得这个评测机和我有仇,写了readgetchar都会超时这么多,最后好像是ios::sync_with_stdio(false);惹的祸... 昨天想找一些水题来写,就看到了这个模拟"水题",想了一下午都不知道怎么搞. 已知一些牛的颜色和位置,求连续相同颜色或连续两种颜色数量相同的区间右端点位…

免费!200块全志XR806开源鸿蒙开发板试用

一板难求的当下,如果上天突然降临一次开发板免费用的活动,我只想说三个字:手慢无!为了让开发者小哥哥小姐姐们体验搭载安谋科技STAR-MC1处理器,面向IoT领域的全志XR806开发板,极术社区特推出2022年新年活动…

你们还留恋windows什么呢?

为什么80%的码农都做不了架构师?>>> 我最近看到一个报道,节录如下: --------------------------------------------- ARM全球总裁Tudor Brown 5月3日表示,预期2015年全球移动PC总量就会达到7.5亿台以上, …

卓老师的这些动图对电子理解真的很有用

01 串行通信在头条电子森林博客中看到一些显示电子系统中信号波形的动图,有助于帮助我们理解传输的机理。特转载如下。1、SPI传输▲ 图1 SPI 数据传输▲ 图1.2 SPI数据传输(2)▲ 图1.3 SPI时序信号2、I2C传输▲ 图1.2.1 I2C总线以及寻址方…