在使用 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. NOIP 2015 提高组 Day2

    期望得分:100+10+60=170 实际得分:100+10+35=145 http://www.cogs.pro/cogs/page/page.php?aid=16 T1 跳石头 时间限制:1 s  ...

  2. .net core 中 identity server 4 之术语

    id4的职责: 保护你的资源 通过本地 账户库(Account Store)或者外部身份提供其 认证用户 提供Session管理以及SSO 管理和认证客户端 发行身份及访问Token给客户端 验证To ...

  3. 使用条件注释判断 IE 浏览器版本

    IE条件注释是一种特殊的HTML注释,这种注释只有IE5.0及以上版本才能理解.比如普通的HTML注释是: <!--This is a comment--> 而只有IE可读的IE条件注释是 ...

  4. 《JavaScript 实战》:JavaScript 实现拖拽缩放效果

    拖拉缩放效果,实现通过鼠标拖动来调整层的面积(宽高)大小,例如选框效果.这里的拖拉缩放比一般的选框复杂一点,能设置八个方位(方向)的固定触发点,能设置最小范围,最大范围和比例缩放. 跟拖放效果一样,程 ...

  5. 指针A - 签到题(顺序三元组)

    给定一个长度为N的数组A=[A1, A2, ... AN],已知其中每个元素Ai的值都只可能是1, 2或者3. 请求出有多少下标三元组(i, j, k)满足1 ≤ i < j < k ≤ ...

  6. 【leetcode 简单】第十一题 搜索插入位置

    给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置. 你可以假设数组中无重复元素. 示例 1: 输入: [1,3,5,6], 5 输 ...

  7. NYOJ 141 Squares (数学)

    题目链接 描述 A square is a 4-sided polygon whose sides have equal length and adjacent sides form 90-degre ...

  8. 天梯赛 L2-012 关于堆的判断 (二叉树)

    将一系列给定数字顺序插入一个初始为空的小顶堆H[].随后判断一系列相关命题是否为真.命题分下列几种: "x is the root":x是根结点: "x and y ar ...

  9. Flask 的一个小应用程序

    传说这是Flask 的最小应用程序:hello.py from flask import Flask app = Flask(__name__) @app.route('/') def hello_w ...

  10. Skipping 'Android SDK Tools, revision 24.0.2'; it depends on 'Android SDK Platform-tools, revision 20' which was not installed.

    前几天,同事问我eclipse android sdk怎么不能更新. 更新界面是显示(mirrors.neusoft.edu.cn:80),但是不能更新. 问题描述如下: URL not found: ...