zoukankan      html  css  js  c++  java
  • 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 释放锁,具体会不会真的释放,得看时机和运气。


    更多内容,可以参阅:

  • 相关阅读:
    判断当前是否运行于Design Mode
    从Setting.settings到Resource.resx
    构造函数强制使用new
    getFullYear 方法
    前端开发中经常使用到的20个正则表达式。
    函数调用模式
    javascript中return的作用
    javascript数组遍历for与for in区别详解
    闭包
    js split 的用法和定义 js split分割字符串成数组的实例代码
  • 原文地址:https://www.cnblogs.com/jasongrass/p/10222551.html
Copyright © 2011-2022 走看看