Mutex 的正确打开方式
在使用 Mutex 在给线程/进程间加锁时,需要注意的问题。
1 AbandonedMutexException
在使用 mutex.WaitOne 时,可能抛出异常 AbandonedMutexException 。
发生了什么?
有一个线程获得了锁,但没有释放锁,则会抛异常,此时数据的完整性可能被破坏。
具体解释见:AbandonedMutexException Class (System.Threading) | Microsoft Docs
比如:在 WaitOne 之后,进程直接退出,后台线程中的 mutex 可能就还没有释放。如何处理?
如果不关心这个异常,可以直接 catch ,继续进行接来下的操作即可。无需再次调用WaitOne。
try
{
try
{
mutex.WaitOne();
}
catch(AbandonedMutexException)
{
// 即使捕获到这个异常,此时也已经获得了锁
}
// do something
}
finally
{
mutex.ReleaseMutex();
}
- 其它内容
考虑如下场景,运行 run.exe 程序,里面获取了 mutex 锁,没有释放直接退出,再次打开 run.exe ,是不会有 AbandonedMutexException 异常的。
但如果同时运行两个(多个) run.exe 程序,第一个获取锁之后不释放直接退出,则第二个 run.exe 会捕捉到 AbandonedMutexException 异常。
原因(猜测):
在只有一个 run.exe 进程时,关闭之后,mutex 对应的内核对象随之释放,第二次运行,新建一个全新的 mutex 内核对象;
而当有两个(多个)run.exe 进程时,mutex 对象始终只有一个。
2 System.ApplicationException
当 WaitOne 对应的 ReleaseMutex 不在同一线程时,会抛出异常:System.ApplicationException:“从不同步的代码块中调用了对象同步方法。”
当出现 ApplicationException 异常时,锁被释放了吗?
没有。只有当调用 WaitOne 的线程被回收之后,才会释放锁,并且下一个 WaitOne 会捕获 AbandonedMutexException 异常。如何避免
在 WaitOne 和 ReleaseMutex 之间不要插入 async/await 方法,否则可能带来线程切换。
在 UI 线程调用 WaitOne 和 ReleaseMutex ,之间倒是可以插入 async/await 方法,最后还是会回到 UI 线程,但是,这样 WaitOne 就是在 UI 线程等啊,卡 UI 啊。
3 关于 WaitOne 与 ReleaseMutex 的次数。
WaitOne 多少次,就要 ReleaseMutex 多少次。
WaitOne 1 次, ReleaseMutex 多次会怎么样?
如果下一个 WaitOne 还没有被调用, ReleaseMutex 多次与一次的效果是一样的,如果有多个 WaitOne 在等待,那 ReleaseMutex 可能会帮其它的 WaitOne 释放锁,具体会不会真的释放,得看时机和运气。
更多内容,可以参阅:
Mutex 的正确打开方式的更多相关文章
- iOS开发小技巧--相机相册的正确打开方式
iOS相机相册的正确打开方式- UIImagePickerController 通过指定sourceType来实现打开相册还是相机 UIImagePickerControllerSourceTypeP ...
- Xcode 的正确打开方式——Debugging(转载)
Xcode 的正确打开方式——Debugging 程序员日常开发中有大量时间都会花费在 debug 上,从事 iOS 开发不可避免地需要使用 Xcode.这篇博客就主要介绍了 Xcode 中几种能 ...
- C#语法——泛型的多种应用 C#语法——await与async的正确打开方式 C#线程安全使用(五) C#语法——元组类型 好好耕耘 redis和memcached的区别
C#语法——泛型的多种应用 本篇文章主要介绍泛型的应用. 泛型是.NET Framework 2.0 版类库就已经提供的语法,主要用于提高代码的可重用性.类型安全性和效率. 泛型的定义 下面定义了 ...
- InnoDB缓冲池预加载在MySQL 5.7中的正确打开方式
InnoDB缓冲池预加载在MySQL 5.7中的正确打开方式 https://mp.weixin.qq.com/s/HGa_90XvC22anabiBF8AbQ 在这篇文章里,我将讨论在MySQL 5 ...
- Console控制台的正确打开方式
Console控制台的正确打开方式 console对象提供了访问浏览器调试模式的信息到控制台 -- Console对象 |-- assert() 如果第一个参数断言为false,则在控制台输出错误信息 ...
- 任务队列和异步接口的正确打开方式(.NET Core版本)
任务队列和异步接口的正确打开方式 什么是异步接口? Asynchronous Operations Certain types of operations might require processi ...
- (一)Redis for Windows正确打开方式
目录 (一)Redis for Windows正确打开方式 (二)Redis for 阿里云公网连接 (三)Redis for StackExchange.Redis 下载地址 官网.中文网1 及 中 ...
- List的remove()方法的三种正确打开方式
转: java编程:List的remove()方法的三种正确打开方式! 2018年08月12日 16:26:13 Aries9986 阅读数 2728更多 分类专栏: leetcode刷题 版权声 ...
- C++11随机数的正确打开方式
C++11随机数的正确打开方式 在C++11之前,现有的随机数函数都存在一个问题:在利用循环多次获取随机数时,如果程序运行过快或者使用了多线程等方法,srand((unsigned)time(null ...
随机推荐
- mysql \G
mysql 命令区分大小写.ego (\G) Send command to mysql server, display result vertically. go (\g) ...
- Image Scaling using Deep Convolutional Neural Networks
Image Scaling using Deep Convolutional Neural Networks This past summer I interned at Flipboard in P ...
- 重构改善既有代码设计--重构手法15:Remove Middle Man (移除中间人)
某个类做了过多的简单委托动作.让客户直接调用受托类. 动机:在Hide Delegate (隐藏委托关系)的“动机”中,谈到了“封装委托对象”的好处.但是这层封装也是要付出代价的,它的代价是:每当客户 ...
- Nodejs文件监控chokidar
最近有个需求是扫描用例,用例是放在svn上,如果每次扫描都去遍历目录的话会有占用太多的io,所以想着用文件监控,有文件变化时只对该文件进行操作. Nodejs里的 chokidar 模块可以更好的对文 ...
- 你知道吗?Java开发的10位牛人
James Gosling 1983年,Gosling获得了加州大学的计算机科学学士学位.1990年,他获得了卡内基梅隆大学的计算机科学博士学位,师从Bob Sproull.在攻读博士期间,他自己开发 ...
- Hadoop面试链接
http://blog.csdn.net/haohaixingyun/article/details/52819457 http://blog.csdn.net/kingmax54212008/art ...
- Codeforces Round #419 (Div. 2) A-E
上紫啦! E题1:59压哨提交成功翻盘 (1:00就做完了调了一个小时,还好意思说出来? (逃)) 题面太长就不复制了,但是配图很可爱所以要贴过来 九条可怜酱好可爱呀 A - Karen and Mo ...
- NYOJ 35 表达式求值 (字符串处理)
题目链接 描述 ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧. 比如输入:&quo ...
- win10环境变量
jdk8 JAVA_HOME D:\devsoft\jdk\jdk1.8 CLASSPATH .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar pa ...
- discuz各个目录与文件的作用说明
discuz下面有很多文件夹以及文件,你们都知道他们是做什么的么?肯定不知道了吧.但是我们有经常遇到这些文件,譬如在后台文件校验操作都遇到某些文件被修改,这时候也需要知道这些文件是有什么作用的.今天就 ...