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(); // 当前线程已到达屏障,等待其它线程到达

 

posted @ 2021-02-24 07:43  温故纳新  阅读(116)  评论(0编辑  收藏  举报