首页 > 编程语言 >【C#Mutex】 initiallyOwned错误引起的缺陷

【C#Mutex】 initiallyOwned错误引起的缺陷

时间:2024-09-15 18:25:07浏览次数:12  
标签:C# initiallyOwned 互斥 mutex Mutex CMutexHelp public WaitOne

临界区只能对同一个进程的不同线程同步,互斥量可以跨进程同步。典型应用场景:两个exe会操作同一个注册表项。

错误代码

封装类

public class CMutexHelp : IDisposable
{
    public CMutexHelp()
    {
        s_mutex.WaitOne();
    }     
    private static Mutex s_mutex = new Mutex( true,"Time202409091406ab");
    public void Dispose()
    {
        s_mutex.ReleaseMutex();
    }
}

使用

 using (var mutex = new CMutexHelp())
 {
     m_reg = new RegistryManager();
 }

错误原因: initiallyOwned参数为true ,已经有信号,无需等待WaitOne。强行WaitOne会让其他进程的WaitOne永远不会结束。解决办法:initiallyOwned改为false。

修改方法一

打开互斥量才等待,新建不等待。

public class CMutexHelp : IDisposable
{
    public CMutexHelp()
    {
        const string name = "Time202409091406ab";
        m_mutex = new Mutex(true, name, out bool createdNew);
        if (!createdNew)
        {
            m_mutex.WaitOne();
        }
    }
    private Mutex m_mutex;
    public void Dispose()
    {
        m_mutex.ReleaseMutex();
        m_mutex.Close();
    }
}

修改方法二:

如果新建互斥量,则释放。画蛇添足。

public class CMutexHelp : IDisposable
{
    public CMutexHelp()
    {
        const string name = "Time202409091406ab";
        m_mutex = new Mutex(true, name, out bool createdNew);
        if (createdNew)
        {
            m_mutex.ReleaseMutex();
        }
        m_mutex.WaitOne();
    }
    private Mutex m_mutex;
    public void Dispose()
    {
        m_mutex.ReleaseMutex();
        m_mutex.Close();
    }
}

相关知识点

构造函数:如果指定名称的互斥量(互斥体)存在,则打开;不存在则创建。只能用一行代码搞定,不能两行代码。第一行:打开互斥量。第二行:如果打开失败,则创建。错误原因:线程一打开互斥量失败,被系统挂起。线程二也是。线程一线程二依次被唤醒,线程一和线程都试图创建互斥量。
如果需要多个互斥,修改"Time202409091406ab"就可以了。不同的互斥用不同的名字。
等待两次,释放一次也会有类似问题。

public CMutexHelp()
{
    s_mutex.WaitOne();
    s_mutex.WaitOne();
}

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

标签:C#,initiallyOwned,互斥,mutex,Mutex,CMutexHelp,public,WaitOne
From: https://blog.csdn.net/he_zhidan/article/details/142093628

相关文章

  • H3C 网络设备定时执行任务
    1、组网拓扑定时执行任务拓扑2、组网需求对Device进行配置,在星期一到星期五的上午八点到下午十八点开启GigabitEthernet1/0/1和GigabitEthernet1/0/2开启端口,其它时间关闭端口,以便起到有效节能的作用。3、配置思路首先确保设备时间的准确性创建关闭GigabitEthernet1/0/1、Gigabit......
  • 一步到位:通过 Docker Compose 部署 EFK 进行 Docker 日志采集
    一、EFK简介Elasticsearch:一个开源的分布式搜索和分析引擎,用于存储和查询日志数据。它是EFK的核心组件,负责高效地存储和检索日志信息。Filebeat:一个轻量级的日志采集器,主要用于将日志文件数据发送到Logstash或Elasticsearch。Filebeat设计用于高效地转发和处理日志......
  • 矩阵连乘(动态规划)(C/C++)最详尽代码注释
    写在所有的前面:本文采用C/C++实现代码目录写在所有的前面:题目说明题目题目出处题目描述Description输入Input输出Output样例Sample限制Hint解答说明方案1:最优分隔点法(动态规划)解题思路代码实现c语言头文件:c++头文件主代码部分:(详尽版本1)主代码部分(题目对应版本)其他解......
  • C++链接的那些事
    接上文OK!Rightnow!  Let's go!今天我们来谈谈链接,什么是链接,C++链接实际上做什么的?链接是一个过程,当我们从源C++文件转到实际的可执行文件(二进制文件)。第一阶段是编译源文件,一旦我们把文件编译好,就需要通过一个叫做链接的过程,现在链接的主要工作是找到每个符号和......
  • C++编译 链接 执行那些事
    OK!Rightnow!  Let's go!如何从源文件开始,实际的文本文档到可执行的二进制代码,写C++程序的基本流程。实际是你有一些C++的源文件,然后将这些源文件给到编译器,编译器将其转成二进制的东西,二进制的东西可能是某种库,或者是可执行的程序。在#符号之后的都是预处理语句......
  • 「数组」堆排序 / 大根堆优化(C++)
    目录概述核心概念:堆堆结构数组存堆思路算法过程up()down()Code优化方案大根堆优化Code(pro)复杂度总结概述在「数组」快速排序/随机值优化|小区间插入优化(C++)中,我们介绍了三种基本排序中的冒泡排序与分治思想结合的算法:快速排序。本文我们来讲第二种基本排......
  • Codeforces Round 968 (Div. 2)
    传送门A.判断首位字符是否相等即可#include<bits/stdc++.h>usingnamespacestd;constintN=1e6+7;voidsolve(){intn;strings;cin>>n>>s;if(s[0]==s[n-1])cout<<"No"<<endl;elsecout<&l......
  • 使用 csharp获取串口 的 全称
    使用的命名控件usingSystem.Management;代码点击查看代码///<summary>///获取串口的全称///</summary>///<returns></returns>publicstaticList<string>GetCompleteNameOfSerialPort(){List<string>serial_port_result=newList&......
  • flask+chartjs实现网页图表自动更新
    Python代码,后端程序提前安装flask,`pipinstallflask`fromflaskimportFlask,jsonify,render_templateimportrandomapp=Flask(__name__)@app.route('/')defindex():returnrender_template('index.html')@app.route('/data')def......
  • .和source与bash或sh执行脚本时的区别
    目录1.source命令2.sh/bash命令3../方式1.source命令source.bash_profile..bash_profile两者等效。source(或点)命令通常用于重新执行刚修改的初始化文档。使用source或.命令时,你可以在当前Shell中直接运行一个Shell脚本,而不需要给脚本添加执行权限。这就......