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 ...
随机推荐
- HTML5-Y音频与视频
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- NOIP模拟赛17
5分.... T1 LOJ 计算几何瞎暴力 维护以下操作: 1.序列末尾加一个数 2.序列全体从小到大排序 3.查询区间和 4.序列全体异或一个数k 序列全体异或一个数,很明显是trie树 那么序列全 ...
- Codeforces Beta Round #34 (Div. 2) E. Collisions
E. Collisions time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- Linux 操作系统下 VI 编辑器常用命令详细介绍
一.Vi 简介 vi是unix世界中最通用的全屏编辑器,linux中是用的是vi的加强版vim,vim同vi完全兼容,vi就是"visual interface"的缩写.它可以执行 ...
- 集合框架小结-List
List集合存储的元素是有序的,可重复的,有索引 List特有方法: 增加 add(index, element); addAll(index, Collection); 删除 remove(inde ...
- LintCode 373: Partition Array
LintCode 373: Partition Array 题目描述 分割一个整数数组,使得奇数在前偶数在后. 样例 给定[1, 2, 3, 4],返回[1, 3, 2, 4]. Thu Feb 23 ...
- 【CodeForces】626 F. Group Projects 动态规划
[题目]F. Group Projects [题意]给定k和n个数字ai,要求分成若干集合使得每个集合内部极差的总和不超过k的方案数.n<=200,m<=1000,1<=ai< ...
- ogg:Extract 进程遇长事务执行 Forcestop 引发的惨案
http://www.linuxidc.com/Linux/2015-04/115777.htm SQL> select t.addr,t.START_DATE from v$transacti ...
- Linux下libevent安装与示例
http://www.cnblogs.com/kunhu/p/3632225.html
- perl6正则 2: 字母,数字,空格,下划线, 字符集
数字, 字母, 下划线 在perl6中, 如果是 数字, 字母, 下划线, 在正则里可以正接写上. > so / True > so 'perl6_' ~~ /_/ True > 非 ...