C# 跨进程 临界区 互斥 进程锁

通过命名 Mutex(互斥体)实现跨进程的同步锁,确保多个进程或线程中只有一个能进入临界区代码块。适用于需要全局资源独占访问的场景。


namespace System
{
    using System.Threading;

    /// <summary>
    /// 跨进程的临界区。
    /// </summary>
    public sealed class ProcessLocker : IDisposable
    {
        /// <summary>
        /// 使用示例。
        /// </summary>
        [System.Diagnostics.Conditional("DEBUG")]
        public static void Test()
        {
            using (new ProcessLocker("TestLocker")) // 成功进入跨进程临界区。
            {
                // 跨进程的临界区。
            } // 成功退出跨进程临界区。
        }

        public ProcessLocker(string name)
        {
            try
            {
                this.name = name;
                bool createdNew;
                // 尝试创建或打开现有的命名Mutex。
                this.mutex = new Mutex(true, name, out createdNew);
                
                // 如果Mutex已存在,则尝试获取所有权
                if (!createdNew)
                {
                    // 没有获取所有权期间,阻塞
                    this.IsWaitOne = this.mutex.WaitOne(-1);
                }
                else
                {
                    // 新创建的Mutex,已拥有所有权
                    this.IsWaitOne = true;
                }
            }
            catch (AbandonedMutexException)
            {
                // 前任所有者未释放Mutex,当前线程获得所有权
                this.IsWaitOne = true;
            }
            catch (Exception ex)
            {
                TraceWriteLine($"Process locker init {name} exception: ", ex);
            }
        }
 
        ~ProcessLocker()
        {
            Dispose(false);
        }
 
        private readonly string name;

        private readonly Mutex mutex;

        /// <summary>
        /// 对象是否已释放。
        /// </summary>
        public bool IsDisposed { get; private set; }

        /// <summary>
        /// 是否成功获取锁。
        /// </summary>
        public bool IsWaitOne { get; private set; }
 
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void Dispose(bool disposing)
        {
            if (!IsDisposed)
            {
                IsDisposed = true;

                if (mutex != null && IsWaitOne)
                {
                    try
                    {
                        // 释放Mutex并销毁资源
                        mutex.ReleaseMutex();
                        if (disposing)
                        {
                            (mutex as IDisposable)?.Dispose();
                        }
                    }
                    catch (Exception ex)
                    {
                        TraceWriteLine($"Process locker dispose {name} exception: ", ex);
                    }
                }
            }
        }

        private static void TraceWriteLine(string message, Exception ex)
        {
            System.Diagnostics.Trace.WriteLine(message + ex);
        }

    }
}

以下是对提供的 ProcessLocker 代码的主要内容和优点的分析:


主要内容

  1. 跨进程临界区实现
    通过命名 Mutex(互斥体)实现跨进程的同步锁,确保多个进程或线程中只有一个能进入临界区代码块。适用于需要全局资源独占访问的场景。

  2. 基于 IDisposable 的资源管理
    类实现 IDisposable 接口,利用 using 语句自动释放锁,避免资源泄漏。通过 Dispose() 方法确保 Mutex 的释放和销毁。

  3. 异常处理机制

    • 捕获 AbandonedMutexException:处理前一个进程未正确释放锁的情况,当前线程直接获得所有权。
    • 记录其他异常(如权限不足、命名冲突等),避免进程崩溃。
  4. 状态跟踪

    • IsWaitOne 属性标记是否成功获取锁。
    • IsDisposed 属性标识对象是否已释放,防止重复释放资源。
  5. 调试支持

    • 提供 Test() 方法(仅在 DEBUG 模式下编译),作为使用示例,帮助开发者快速理解用法。

代码优点

  1. 封装性与易用性
    将底层的 Mutex 操作封装成简洁的 ProcessLocker 类,用户只需通过 using 块即可实现跨进程同步,无需直接处理 Mutex 的复杂性。

  2. 健壮的资源管理

    • 结合 IDisposable 和终结器(~ProcessLocker()),确保即使未显式调用 Dispose(),资源也会在垃圾回收时释放。
    • 使用 GC.SuppressFinalize 优化性能,避免重复释放。
  3. 异常鲁棒性

    • 处理 AbandonedMutexException 避免因前序进程崩溃导致的死锁。
    • 在构造函数和 Dispose 中捕获异常并记录日志,提升系统稳定性。
  4. 跨进程支持
    基于命名 Mutex 的机制天然支持跨进程同步,适用于多进程协作场景(如单实例应用、共享文件访问等)。

  5. 调试友好性
    Test() 方法提供直观的使用示例,配合 Conditional("DEBUG") 特性,确保示例代码仅在调试时编译,不影响生产环境。

  6. 状态反馈
    IsWaitOne 属性允许调用者检查是否成功获取锁,便于后续逻辑处理或错误排查。


潜在改进点

  • 全局命名空间支持
    Windows 系统下,跨会话的全局 Mutex 需添加 Global\ 前缀(如 Global\TestLocker)。当前代码未显式处理,可能限制跨会话使用。
    Mutex 是否需添加 Global\ 前缀 文档

  • 锁获取失败处理
    构造函数中若 WaitOne 失败(如超时),IsWaitOne 会为 false,但未提供显式错误通知机制,调用者需主动检查该属性。

  • 线程安全增强
    可进一步确保多线程环境下 Dispose() 的原子性,但现有代码通过 IsDisposed 标记已具备基础防护。


总结

ProcessLocker 类是一个高效、健壮的跨进程同步工具,通过封装 Mutex 和资源管理机制,简化了多进程环境下的临界区控制。其异常处理和状态跟踪设计使其适合高可靠性场景,而清晰的接口和调试支持则降低了使用门槛。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值