C#多线程访问资源

文章目录

  • C#多线程访问资源
      • [1.1 锁机制](#1.1 锁机制)
      • [1.2 信号量机制](#1.2 信号量机制)
      • [1.3 事件与信号](#1.3 事件与信号)
      • [1.4 原子操作](#1.4 原子操作)
      • [1.5 线程安全集合](#1.5 线程安全集合)
      • [1.6 避免共享状态](#1.6 避免共享状态)
      • [1.7 异步与并行](#1.7 异步与并行)
      • [1.8 选择策略](#1.8 选择策略)

C#多线程访问资源

在 C# 中,多线程访问共享资源需要通过同步机制来保证线程安全。以下是常见的解决方案及其适用场景:

1.1 锁机制

  1. lock 关键字

    • 基于 Monitor 类,确保代码块同一时间仅一个线程进入。
    • 适用场景:简单临界区保护。
    csharp 复制代码
    private readonly object _lockObj = new object();
    lock (_lockObj) 
    {
        // 访问共享资源
    }
  2. Monitor 类

    • 提供更灵活的控制(如超时机制)。
    csharp 复制代码
    Monitor.Enter(_lockObj);
    try { /* 操作资源 */ }
    finally { Monitor.Exit(_lockObj); }
  3. Mutex (互斥锁)

    • 跨进程同步,适用于多进程共享资源。
    csharp 复制代码
    using var mutex = new Mutex(false, "GlobalMutexName");
    mutex.WaitOne();
    try { /* 操作资源 */ }
    finally { mutex.ReleaseMutex(); }
  4. SpinLock (自旋锁)

    • 通过循环等待避免上下文切换,适用于极短临界区。
    csharp 复制代码
    SpinLock spinLock = new SpinLock();
    bool lockTaken = false;
    spinLock.Enter(ref lockTaken);
    try { /* 操作资源 */ }
    finally { if (lockTaken) spinLock.Exit(); }

1.2 信号量机制

  1. Semaphore / SemaphoreSlim

    • 控制同时访问资源的线程数量。
    csharp 复制代码
    SemaphoreSlim semaphore = new SemaphoreSlim(3); // 允许3个线程进入
    await semaphore.WaitAsync();
    try { /* 操作资源 */ }
    finally { semaphore.Release(); }
  2. ReaderWriterLockSlim

    • 读写分离锁,允许多读单写。
    csharp 复制代码
    ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();
    rwLock.EnterReadLock();  // 读模式
    try { /* 读取资源 */ }
    finally { rwLock.ExitReadLock(); }
    
    rwLock.EnterWriteLock(); // 写模式
    try { /* 修改资源 */ }
    finally { rwLock.ExitWriteLock(); }

1.3 事件与信号

  1. ManualResetEvent / AutoResetEvent

    • 通过信号控制线程阻塞与唤醒。
    csharp 复制代码
    ManualResetEvent mre = new ManualResetEvent(false);
    mre.WaitOne();    // 等待信号
    mre.Set();        // 发送信号
  2. Barrier (屏障)

    • 同步多个线程到同一阶段。
    csharp 复制代码
    Barrier barrier = new Barrier(3); // 等待3个线程到达
    barrier.SignalAndWait();          // 每个线程调用此方法
  3. CountdownEvent

    • 等待指定数量的操作完成。
    csharp 复制代码
    CountdownEvent cde = new CountdownEvent(3);
    cde.Signal();  // 每个线程完成后调用
    cde.Wait();    // 等待所有完成

1.4 原子操作

  1. Interlocked 类

    • 提供原子操作(如递增、比较交换)。
    csharp 复制代码
    int value = 0;
    Interlocked.Increment(ref value); // 原子递增

1.5 线程安全集合

  1. ConcurrentQueue / ConcurrentDictionary 等

    • 内置线程安全的集合,避免手动同步。
    csharp 复制代码
    var queue = new ConcurrentQueue<int>();
    queue.Enqueue(1);
    if (queue.TryDequeue(out var item)) { /* 处理元素 */ }

1.6 避免共享状态

  1. 不可变对象

    • 使用 readonly 或不可变集合(如 ImmutableList),确保数据不可变。
    csharp 复制代码
    var list = ImmutableList.Create<int>();
    list = list.Add(1); // 返回新实例,原数据不变
  2. 线程本地存储

    • 使用 ThreadLocal<T> 或 [ThreadStatic] 为每个线程创建独立副本。
    csharp 复制代码
    ThreadLocal<int> threadLocal = new ThreadLocal<int>(() => 0);
    int localValue = threadLocal.Value;

1.7 异步与并行

  1. async/await 与异步锁

    • 在异步代码中使用 SemaphoreSlim.WaitAsync()。
    csharp 复制代码
    private SemaphoreSlim asyncLock = new SemaphoreSlim(1);
    await asyncLock.WaitAsync();
    try { /* 异步操作资源 */ }
    finally { asyncLock.Release(); }
  2. TPL (任务并行库)

    • 使用 Parallel.For 或 Task 时确保资源安全。
    csharp 复制代码
    Parallel.For(0, 10, i => 
    {
        // 需要内部同步机制
    });

1.8 选择策略

  • 简单临界区 :优先使用 lock 或 Monitor。
  • 读写分离 :使用 ReaderWriterLockSlim。
  • 高并发读:不可变对象或并发集合。
  • 异步场景 :SemaphoreSlim.WaitAsync()。
  • 跨进程同步 :Mutex。

通过合理选择同步机制,可以平衡性能与线程安全。

相关推荐
samble19 小时前
从零搭建灌装监控系统(十八):自定义控件,三色灯与状态指示
c#·wpf·mvvm·modbus·工业控制
jun_bai19 小时前
使用Aspose实现word文档合并,内容替换
windows·c#·word
字节暗面1 天前
客户端上报不可信:游戏服务端数据校验与对局重演设计
c#·游戏开发·服务端校验·反作弊
chingho1 天前
GitHub上这10个C#项目,不仅实用,还怪好玩的
c#·github·.net·开源项目
半亩码田1 天前
C#转Python第5.1篇:异步编程:asyncio vs async/await,语法相似但机制不同
开发语言·python·c#
阿华田5121 天前
Java 类加载冲突实战:解决 is not an instance of
c#·linq
samble1 天前
从零搭建灌装监控系统(十七):LiveCharts 实时温度曲线
c#·wpf·mvvm·modbus·工业控制
淡海水2 天前
02-07-原理篇-GC暂停时间的本质
开发语言·unity·c#·gc·暂停时间
小羊没烦恼!2 天前
OS X 上使用.NET开发应用程序
开发语言·前端·数据库·人工智能·c#·策略模式
Behavior2 天前
Unity 7.0 Alpha 拆解:编辑器干掉 Mono 换 CoreCLR
c#·unity3d·游戏开发