.NET进阶篇06-async异步、thread多线程4 (2)

Mutex互斥锁提供跨多个进程同步一个类,定义互斥锁的时候可以指定互斥锁的名称,这样系统能够识别,所以在另一个进程中定义的互斥,其他进程也是可以访问到的,Mutex.OpenExisting()便可以得到。

bool createdNew = false;
Mutex mutex = new Mutex(false"ProCharpMutex"out createdNew);
if (mutex.WaitOne())
{
    try
    {
        //synchronized region
    }
    finally
    {
        mutex.ReleaseMutex();
    }
}

介于此我们可以用来禁止一个应用程序启动两次,一般我们通过进程的名称来判断,这里我们使用Mutex实现

bool createdNew = false;
Mutex mutex = new Mutex(false"SingletonWinAppMutex"out createdNew);
if (!createdNew)
{
    MessageBox.Show("应用程序已经启动过了");
    Application.Exit();
    return;
}
6、Semaphore

Semaphore信号量和互斥类似,区别是,信号量可以同时让多个线程使用,是一种计数的互斥锁定。通过计数允许同时有几个线程访问受保护的资源。也可以指定信号量名称以使在多个进程间共享

Semaphore和上面Mutex都是继承自WaitHandle基类,WaitHandle用于等待一个信号的设置,嗲用Wait,线程会等待接收一个与等待句柄相关的信号

SemaphoreSlim是对Semaphore的轻量替代版本(它不继承WaitHandle),SemaphoreSlim(int initialCount, int maxCount)构造函数可指定最大并发个数,然后在线程内通过SemaphoreSlim的Wait等到直到来接收信号是否可以进去受保护代码块了,最后记得要Release,不然下一个线程获取不到准许进入的信号

7、Events

Events事件锁不同于委托中的事件,在System.Threading命名空间下,用于系统范围内的事件资源的同步,有AutoResetEvent自动事件锁、ManualResetEvent手动事件锁以及轻量版本ManualResetEventSlim

1、AutoResetEvent

AutoResetEvent也是继承自waitHandle类的,也是通过WaitOne来等待直到有信号,它有两种状态:终止和非终止,可以调用set和reset方法使对象进入终止和非终止状态。通俗点就是set有信号,另一个线程可以进入了,reset非终止无信息,其他线程就阻塞了。自动的意思就是一个线程进入了,自动Reset设置无信号了其他线程就进不去了。类似现实中的汽车收费口,一杆一车模式

private AutoResetEvent autoEvent = new AutoResetEvent(false);
public void DoThis()
{
    autoEvent.WaitOne();
    //执行同步代码块
    autoEvent.Set();
}

.NET进阶篇06-async异步、thread多线程4

2、ManualResetEvent

手动事件锁和自动的区别在于,手动事件锁没有信号时会阻塞一批线程的,有信号时,所有线程都运行,同时唤醒多个线程,除非手动Reset再阻塞,类似现实场景中火车道路口的栅栏,落杆拦截一批人,起杆则一批人蜂拥通过,用法和上面一样,WaitOne等待信号,结束时通过Set来通知有信号了,可以通过了

.NET进阶篇06-async异步、thread多线程4

3、ManualResetEventSlim

ManualResetEventSlim通过封装 ManualResetEvent提供了自旋等待和内核等待的混合锁模式。如果需要跨进程或者跨AppDomain的同步,那么就必须使用ManualResetEvent。ManualResetEventSlim使用Wait来阻塞线程,支持任务的取消。和SemaphoreSlim的Wait一样,内部先通过用户模式自旋然后再通过内核模式效率更高

8、ReaderWriterLock

ReaderWriterLock读写锁不是从限定线程个数的角度来保护资源,而是按读写角度来区分,就是你可以锁定当某一类线程(写线程)中一个进入受保护资源时,另一类线程(读线程)全部阻塞。如果没有写入线程锁定资源,就允许多个读取线程方法资源,但只能有一个写入线程锁定该资源

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjjgs.html