在使用 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 的正确打开方式的更多相关文章

  1. iOS开发小技巧--相机相册的正确打开方式

    iOS相机相册的正确打开方式- UIImagePickerController 通过指定sourceType来实现打开相册还是相机 UIImagePickerControllerSourceTypeP ...

  2. Xcode 的正确打开方式——Debugging(转载)

    Xcode 的正确打开方式——Debugging   程序员日常开发中有大量时间都会花费在 debug 上,从事 iOS 开发不可避免地需要使用 Xcode.这篇博客就主要介绍了 Xcode 中几种能 ...

  3. C#语法——泛型的多种应用 C#语法——await与async的正确打开方式 C#线程安全使用(五) C#语法——元组类型 好好耕耘 redis和memcached的区别

    C#语法——泛型的多种应用   本篇文章主要介绍泛型的应用. 泛型是.NET Framework 2.0 版类库就已经提供的语法,主要用于提高代码的可重用性.类型安全性和效率. 泛型的定义 下面定义了 ...

  4. InnoDB缓冲池预加载在MySQL 5.7中的正确打开方式

    InnoDB缓冲池预加载在MySQL 5.7中的正确打开方式 https://mp.weixin.qq.com/s/HGa_90XvC22anabiBF8AbQ 在这篇文章里,我将讨论在MySQL 5 ...

  5. Console控制台的正确打开方式

    Console控制台的正确打开方式 console对象提供了访问浏览器调试模式的信息到控制台 -- Console对象 |-- assert() 如果第一个参数断言为false,则在控制台输出错误信息 ...

  6. 任务队列和异步接口的正确打开方式(.NET Core版本)

    任务队列和异步接口的正确打开方式 什么是异步接口? Asynchronous Operations Certain types of operations might require processi ...

  7. (一)Redis for Windows正确打开方式

    目录 (一)Redis for Windows正确打开方式 (二)Redis for 阿里云公网连接 (三)Redis for StackExchange.Redis 下载地址 官网.中文网1 及 中 ...

  8. List的remove()方法的三种正确打开方式

    转: java编程:List的remove()方法的三种正确打开方式! 2018年08月12日 16:26:13 Aries9986 阅读数 2728更多 分类专栏: leetcode刷题   版权声 ...

  9. C++11随机数的正确打开方式

    C++11随机数的正确打开方式 在C++11之前,现有的随机数函数都存在一个问题:在利用循环多次获取随机数时,如果程序运行过快或者使用了多线程等方法,srand((unsigned)time(null ...

随机推荐

  1. HDU 1211 EXGCD

    EXGCD的模板水题 RSA算法给你两个大素数p,q定义n=pq,F(n)=(p-1)(q-1) 找一个数e 使得(e⊥F(n)) 实际题目会给你e,p,q计算d,$de \mod F(n) = 1$ ...

  2. linux 中 permission denied的问题

    想在linux中运行一个脚步,却提示permission denied. 文件权限不允许. 为了获得执行权限,借助chmod指令修改文件权限即可. 1.如果是运行程序时出现此提示,一般执行chmod ...

  3. nginx目录路径重定向[转]

    如果希望域名后边跟随的路径指向本地磁盘的其他目录,而不是默认的web目录时,需要设置nginx目录访问重定向. 应用场景:dashidan.com/image自动跳转到dashidan.com/fol ...

  4. Zepto学习笔记

    Zepto和jQuery的很多API都很一致,思路也很相似,我不会全都整理出来,只是把一些平时用到了的或者不同的地方需要注意一下的地方总结出来.另外,Zepto现在还不是很成熟,无论是对大小写的敏感还 ...

  5. 分享一个彻底冻结对象的函数——来自阮一峰老师的《ECMAScript 6 入门》

    var constantize = (obj) => { Object.freeze(obj); Object.keys(obj).forEach( (key, i) => { if ( ...

  6. 【Nginx】修改响应头,根据不同请求IP重定向到不同IP

    背景: 使用CAS登录的过程中会涉及到三次重定向,如果在同一个局域网内,是没有任何问题的,但如果涉及到跨网访问,这个问题就比较蛋疼了. 解决思路: 通过Nginx对要访问的系统进行代理,根据请求IP来 ...

  7. 简易安装sqoop

    版本 :hive-0.13.1-cdh5.3.6.tar.gz 1:解压 然后 进到 conf 目录 修改 sqoop-env.sh   2:如果使用mysql 数据库 要将 mysql驱动包拷贝到 ...

  8. 二. Jmeter--关联

    1. 首先建立一个线程组(Thread Group),为什么所有的请求都要加入线程组这个组件呢?不加不行吗?答案当然是不行的.因为jmeter的所有任务都必须由线程处理,所有任务都必须在线程组下面创建 ...

  9. 【zTree】zTree展开树节点

    今天在做zTree树的时候想着将第一级tree展开,于是利用下面方法: /** * 展开树节点的第一层 */ function openFirstTreenode(){ // 获取树对象 var tr ...

  10. ORACLE ASM中查询表空间使用情况、数据文件路径、裸设备磁盘总大小剩余大小

    在ASM中:查询所有磁盘名称.总大小.剩余大小:单位MB-----查看组的信息(总大小)select name,total_mb, free_mb from v$asm_diskgroup; ---查 ...