C# 线程同步相关类
1 Mutex-互斥体
Mutex可以用于线程同步也可以用于进程同步
构造函数 public Mutex(bool initiallyOwned, string? name, out bool createdNew)
initiallyOwned-是否具有互斥体的初始所有权,false-意味着调用构造函数的线程并未持有该互斥体,其它线程调用WaitOne()方法的线程会立即得到该互斥体;true-意味着调用构造函数的线程持有了该互斥体,其它线程调用WaitOne()方法的线程会被阻塞等待持有线程ReleaseMutex之后才能得到该互斥体
name-标识,如果名称以前缀“Global\”开头,则 mutex 在所有终端服务器会话中均为可见。如果名称以前缀“Local\”开头,则 mutex 仅在创建它的终端服务器会话中可见
createdNew-如果创建了局部互斥体(即,如果 name 为 null 或空字符串)或指定的命名系统互斥体,则createdNew 返回true;如果指定的命名系统互斥体已存在,则为 createdNew 返回false,可以用这个防止应用程序被打开两次
如果在使用Mutex时报错“由于出现被放弃的 mutex,等待过程结束。”,很可能就是线程调用了WaitOne方法获取到该互斥体使用完后没有调用ReleaseMutex方法释放互斥体
2 Interlocked-为多个线程的共享变量提供原子操作
使用方法:
Interlocked.Increment(ref value); // 原子自增1
Interlocked.Decrement(ref value); // 原子自减1
Interlocked.Exchange(ref value, 3344); // 以原子操作的方式把value赋值为3344
Interlocked.Add(ref value, 100); // 以原子操作的方式使value加100
3 AutoResetEvent 和 ManualResetEventSlim-线程同步事件
https://www.cnblogs.com/tomorrow0/p/13905849.html
4 SemaphoreSlim-用于限制同时访问同一共享资源的线程数
使用方法:
public static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(2); // 定义一个SemaphoreSlim 实例semaphoreSlim ,该semaphoreSlim 可以立即授权给两个线程,当已授权的线程数超过2个时,其它线程只能等待其它线程释放才能获取授权
semaphoreSlim.Wait(); // 等待进入该semaphoreSlim ,也可以异步等待(WaitAsync)
semaphoreSlim.Release() // 释放该semaphoreSlim 实例一次,允许一个等待的线程可以进入该semaphoreSlim 实例
5 CountdownEvent-在收到特定次数信号后使等待线程继续运行的同步基元
使用方法:
CountdownEvent countdownEvent = new CountdownEvent(3); // 定义一个CountdownEvent实例
countdownEvent.Wait(); // 阻止当前线程,直到该countdownEvent 收到指定信号次数(3次)继续运行
countdownEvent.Signal(); // 发送一次信号
参考链接:
https://www.cnblogs.com/tomorrow0/p/14219995.html
6 Barrier-用于组织多个线程在及时在某个时刻会面
Barrier构造方法提供了一个回调函数,当使用该Barrier的线程调用SignalAndWait方法的次数达到Barrier指定注册数(Barrier构造函数指定)时该回调方法会执行
当Barrier的注册数 > 使用该Barrier的线程数 : 这时Barrier的回调方法不会执行,因为线程调用SignalAndWait方法的次数达不到Barrier指定注册数
当Barrier的注册数 < 使用该Barrier的线程数:报错“The number of threads using the barrier exceeded the total number of registered participants.”
使用方法:
Barrier barrier = new Barrier(2, b => { Console.WriteLine($"当前阶段:{b.CurrentPhaseNumber}"); }); // 定义一个Barrier 实例,注册数为2,当使用该Barrier 实例的线程调用SignalAndWait次数达到该注册数时,回调方法会执行
barrier.SignalAndWait(); // 当前线程已到达屏障,等待其它线程到达