C# Mutex实现线程与进程同步的技术指南

 更新时间:2025年11月07日 09:27:53   作者:拾荒的小海螺  
在多线程或多进程程序中,如果多个线程/程序同时访问同一资源,很容易导致数据冲突或程序异常,为了解决这种问题,C# 提供了强大的同步原语Mutex,下面我们就来看看它的具体使用吧

1、简述

在多线程或多进程程序中,如果多个线程/程序同时访问同一资源(文件、数据库、端口、共享内存),很容易导致数据冲突或程序异常。为了解决这种“并发访问冲突”,C# 提供了强大的同步原语 —— Mutex(互斥量)

本文将深入讲解:

  • 什么是 Mutex
  • Mutex 的常见应用场景
  • 本地线程级锁与跨进程锁的区别
  • 实战样例(单实例程序、防止重复写文件、多线程同步)

2、什么是 Mutex?

Mutex(Mutual Exclusion)互斥量 是一种同步机制,用于确保同一时间只有一个线程或进程能够访问特定资源。

关键特征:

  • Mutex 可以跨线程同步,也可以跨进程同步;
  • lock 语句不同,Mutex 可以命名;
  • 可以通过名称在不同程序间共享。

3、实践样例

3.1 基本使用方法

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        using (var mutex = new Mutex())
        {
            mutex.WaitOne(); // 请求进入临界区
            Console.WriteLine("线程进入临界区...");

            Thread.Sleep(2000); // 模拟工作

            Console.WriteLine("线程退出临界区。");
            mutex.ReleaseMutex(); // 释放锁
        }
    }
}

输出:

线程进入临界区...
线程退出临界区。

当多个线程运行这段代码时,会 排队等待 获取锁,避免同时访问资源。

3.2 跨进程 Mutex(命名互斥量)

通过为 Mutex 指定名称(例如 "Global\\MyAppMutex"),可以实现跨进程级的锁机制。即使是两个不同的程序实例,也可以共享同一把互斥锁。

using System;
using System.Threading;

class Program
{
    static Mutex? _mutex;

    static void Main()
    {
        bool createdNew;

        // 命名 Mutex,可被不同进程共享
        _mutex = new Mutex(true, "Global\\MyUniqueAppName", out createdNew);

        if (!createdNew)
        {
            Console.WriteLine("程序已在运行,请勿重复启动!");
            return;
        }

        Console.WriteLine("程序运行中,按任意键退出...");
        Console.ReadKey();

        _mutex.ReleaseMutex();
    }
}

运行两次该程序:

程序已在运行,请勿重复启动!

这样可以防止用户误启动多个实例。

3.3 多线程写文件保护

多个线程同时写文件时,如果没有同步,很容易导致文件被覆盖或数据混乱。

using System;
using System.IO;
using System.Threading;

class Program
{
    static readonly Mutex fileMutex = new Mutex();

    static void Main()
    {
        for (int i = 0; i < 5; i++)
        {
            int threadId = i;
            new Thread(() => WriteLog(threadId)).Start();
        }
    }

    static void WriteLog(int id)
    {
        fileMutex.WaitOne(); // 获取锁

        try
        {
            string message = $"线程 {id} 在 {DateTime.Now} 写入日志\n";
            File.AppendAllText("log.txt", message);
            Console.WriteLine($"✅ {message}");
            Thread.Sleep(500); // 模拟写入时间
        }
        finally
        {
            fileMutex.ReleaseMutex(); // 释放锁
        }
    }
}

输出:

线程 0 在 2025/10/24 写入日志
线程 1 在 2025/10/24 写入日志
...

文件内容会有序写入,不会出现错乱或覆盖。

3.4 跨进程文件访问控制

两个不同的程序(甚至是不同用户进程)写同一个文件时,也可以使用命名 Mutex防止冲突:

using System;
using System.IO;
using System.Threading;

class Program
{
    static void Main()
    {
        using (var mutex = new Mutex(false, "Global\\FileWriteLock"))
        {
            Console.WriteLine("等待文件锁...");
            mutex.WaitOne();

            try
            {
                File.AppendAllText("shared.txt", $"写入时间:{DateTime.Now}\n");
                Console.WriteLine("写入完成。");
                Thread.Sleep(3000);
            }
            finally
            {
                mutex.ReleaseMutex();
            }
        }
    }
}

如果同时启动多个实例,它们会依次写入 shared.txt 文件,避免数据混乱。

3.5 线程安全的资源管理

你可以用 Mutex 保护一些昂贵资源(例如数据库连接、缓存文件、串口设备):

class SharedResource
{
    private readonly Mutex _mutex = new Mutex();
    private int _counter = 0;

    public void SafeIncrement()
    {
        _mutex.WaitOne();
        try
        {
            _counter++;
            Console.WriteLine($"当前计数:{_counter}");
        }
        finally
        {
            _mutex.ReleaseMutex();
        }
    }
}

4、结语

通过本文,你已经掌握了:

  • Mutex 的概念与适用场景;
  • 单实例程序控制;
  • 多线程与跨进程同步;
  • 文件写入保护与资源安全访问。

Mutex 是 C# 同步机制中最强大的工具之一,特别适用于需要跨进程协调资源的场景(如后台服务、日志系统、文件写入、硬件访问等)。

到此这篇关于C# Mutex实现线程与进程同步的技术指南的文章就介绍到这了,更多相关C# Mutex线程与进程同步内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于C#实现rar文件密码破解工具

    基于C#实现rar文件密码破解工具

    这篇文章主要为大家详细介绍了如何基于C#实现一个rar文件密码破解工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-07-07
  • C#实现扫描枪扫描二维码并打印(实例代码)

    C#实现扫描枪扫描二维码并打印(实例代码)

    这篇文章主要介绍了C#实现扫描枪扫描二维码并打印,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-01-01
  • WPF实现多运算符表达式计算器

    WPF实现多运算符表达式计算器

    这篇文章主要为大家详细介绍了WPF实现多运算符表达式计算器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • C#移除所有事件绑定的方法

    C#移除所有事件绑定的方法

    这篇文章主要介绍了C#移除所有事件绑定的方法,实例分析了C#事件绑定的移除方法,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-03-03
  • DataReader、DataSet、DataAdapter和DataView使用介绍

    DataReader、DataSet、DataAdapter和DataView使用介绍

    ADO.NET提供两个对象用于检索关系型数据并把它存储在内存中,分别是DataSet和DataReader,本文将详细介绍这几个对象的应用,有需求的朋友可以了解下
    2012-11-11
  • c#一个定时重启的小程序实现代码

    c#一个定时重启的小程序实现代码

    今天有个朋友找我问有没有一些能像Windows一样计划任务重启的软件,我也不清楚。他它说能让我做一个给他它么?我考虑了一下,他的服务器都是有安装.NET框架的,那可以用.NET来使下~~!
    2008-09-09
  • C#泛型详解及关键字作用

    C#泛型详解及关键字作用

    这篇文章主要来讲讲c#中的泛型,因为泛型在c#中有很重要的位置,对于写出高可读性,高性能的代码有着关键的作用,大家都知道泛型公共语言运行库是非常重要功能,那么为什么使用泛型呢,带着这个问题一起通过本文学习下吧
    2021-08-08
  • C#关键字in、out、ref的作用与区别

    C#关键字in、out、ref的作用与区别

    这篇文章介绍了C#关键字in、out、ref的作用与区别,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • C#实现文本文件读写方法汇总

    C#实现文本文件读写方法汇总

    本文给大家汇总介绍了C#实现文本文件读写的方法,十分的简单实用,有需要的小伙伴可以参考下。
    2015-06-06
  • C#通过重写Panel改变边框颜色与宽度的方法

    C#通过重写Panel改变边框颜色与宽度的方法

    这篇文章主要介绍了C#通过重写Panel改变边框颜色与宽度的方法,涉及C#针对Panel控件的重写与属性设置技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-08-08

最新评论