当前位置: 首页 > 知识库问答 >
问题:

C#互斥体处理

蓟辰沛
2023-03-14

我不确定是否已经很好地理解了如何处理互斥。我需要一个进程只运行一次,但如果由于任何原因它意外崩溃或关闭,我还需要重置被放弃的互斥锁。

出于这个原因,我做了一个助手调用,试图获取一个具有超时的互斥锁(由名称标识)。如果获取互斥锁失败,则返回NULL,否则返回将由方法调用者处理的互斥锁。如果互斥锁被放弃,我将重置它,并将请求视为失败(不是代码被插入以在周期性过程中使用的问题,如果锁有时失败,那么过程将恢复到下一次运行)。

我要问的是,是否有一些情况我没有考虑到,可能会导致我的问题

这里的代码:

public class MutexManager
{
    /// <summary>
    /// Try to acquire a global mutex
    /// </summary>
    /// <param name="mutexName">Mutex unique name</param>
    /// <param name="timeout_ms">Timeout in milliseconds (Optional : default = 5000, if <= 0 no timeout is applied, infinite wait and possibile daeadlock) </param>
    /// <returns>The acquired Mutex or null if Mutex can not be acquired</returns>
    public static Mutex TryRegister(string mutexName, int timeout_ms = 5000)
    {
        // unique id for global mutex - Global prefix means it is global to the machine
        string mutexId = string.Format("Global\\{{{0}}}", mutexName);

        bool createdNew;
        var allowEveryoneRule =new MutexAccessRule(    new SecurityIdentifier(WellKnownSidType.WorldSid
                                                       , null)
                                                       , MutexRights.FullControl
                                                       , AccessControlType.Allow
                                                       );
        Mutex mutex = null;
        {
            mutex = new Mutex(false, mutexId, out createdNew);
            var hasHandle = false;

            try
            {
                hasHandle = mutex.WaitOne(timeout_ms, false);
                if (hasHandle == false)
                    return null;
                else
                    return mutex;
            }
            catch (AbandonedMutexException)
            {
                mutex.ReleaseMutex();
                mutex.Close();
                mutex.Dispose();
                return null;
            }
            catch (Exception err)
            {
                return null;
            }
        }
    }
}

这里我将如何使用上面的类。下面的代码用于定期过程(通过windows scheduler进行调度),因此,如果有时出错不是问题(下一次运行将完成此工作),重要的是不存在争用条件或死锁

using ( var mutex = MutexManager.TryRegister("procedureName") )
{
    ...DO WORK
}

共有1个答案

叶琦
2023-03-14

互斥锁由单个进程“拥有”,如果进程崩溃或关闭,互斥锁将被释放。

如果进程崩溃,Mutex被释放,那么它被认为是“放弃的”,这是一种信号,表明原始进程不再拥有它——但也没有明确释放它。

在您的问题或代码中,我不太理解的是如何处理废弃的互斥体。只有在先前没有放弃的情况下,助手才会返回互斥对象。如果它被放弃,代码将成功检索互斥体,然后释放它并返回,而根本不提供互斥体。

这可能是目的,但从问题的措辞来看,这有点难以理解。如果帮助程序打算重置并返回互斥锁,则放弃的MutexException的处理看起来不正确,因为它将始终返回null。

 类似资料:
  • 问题内容: 我想知道Node.js中的数据访问是否需要互斥锁/锁。例如,假设我已经创建了一个简单的服务器。服务器提供了几种协议方法,可以添加到内部阵列中或从内部阵列中删除。我需要使用某种互斥量保护内部阵列吗? 我了解Javascript(因此Node.js)是单线程的。我只是不清楚事件的处理方式。事件会中断吗?如果真是这样,我的应用程序可能正在读取数组的过程中,被打断以运行事件回调以更改数组,然后

  • 问题内容: 阅读有关锁定PHP的一些文章。 它们主要都直接指向http://php.net/manual/en/function.flock.php。 本页讨论如何在硬盘上打开文件! 真的是这样吗?我的意思是,这使锁定变得非常昂贵-这意味着每次要锁定时,我都必须访问硬盘)= 能再给我一个令人愉快的消息安慰我吗? 编辑: 由于我已经收到了一些答复,我想问这个。 我的脚本只能由一个或多个线程运行?因为

  • 互斥是多线程系统中用于控制访问的一个原对象(primitive object)。下面的例子给出了它最基本的用法: std::mutex m; int sh; //共享数据 // … m.lock(); // 对共享数据进行操作: sh += 1; m.unlock(); 在任何时刻,最多只能有一个线程执行到lock()和unlock()之间的区域(通常称为临界区)。当第一个线程正在临界区执行时

  • Go语言包中的 sync 包提供了两种锁类型:sync.Mutex 和 sync.RWMutex。 Mutex 是最简单的一种锁类型,同时也比较暴力,当一个 goroutine 获得了 Mutex 后,其他 goroutine 就只能乖乖等到这个 goroutine 释放该 Mutex。 RWMutex 相对友好些,是经典的单写多读模型。在读锁占用的情况下,会阻止写,但不阻止读,也就是多个 gor

  • 上面的例子中,我们看过了如何在多个协程之间原子地访问计数器,对于更复杂的例子,我们可以使用Mutex来在多个协程之间安全地访问数据。 package main import ( "fmt" "math/rand" "runtime" "sync" "sync/atomic" "time" ) func main() { // 这个例子的状态就

  • 线程使用互斥量保护共享资源 线程使用互斥量保护共享资源 源码/* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-08-24 yangjie the first versi