Semaphore和SemaphoreSlim实现并发同步

Semaphore,中文译为信号灯。在C#中,它可以允许指定数量的线程同时访问共享资源,而其他的线程必须等待。

即现在有5个线程同时运行,但Semaphore指定2个线程可以同时访问某一共享资源。当执行Semaphore.Wait()时,只有2个线程可以同时进入访问共享资源,而其他三个线程则阻塞等待,直到某一个线程执行Semaphore.Release()时,就会释放一个阻塞的线程。

即同时访问共享资源的线程数量必须小于或等于Semaphore指定的数量。

SemaphoreSlim是Semaphore的轻量型实现,即占用资源没有Semaphore多。

Semaphore可以实现进程和线程并发同步;

SemaphoreSlim只能实现线程的并发同步。

代码如下:

        public static int Counter = 0;
        //指定2个线程可以同时访问共享资源
        static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(2);
        static void WorkOnSemaphore(string threadName, int seconds)
        {
            Console.WriteLine($"{threadName} 正在等待中...");
            //阻塞指定数量之外的线程
            semaphoreSlim.Wait();
            Console.WriteLine($"{threadName} 执行中...");
            //因为我们指定了2个线程可以同时访问,在此做一个标记,如果是2个线程之外的,必须等待
            Interlocked.Increment(ref Counter);
            if(Counter%2==0)
                Console.WriteLine("其他线程等待中...");
            //Thread.Sleep(TimeSpan.FromSeconds(seconds));
            Console.WriteLine($"{threadName} 执行完毕!");
            semaphoreSlim.Release();
        }

Main方法中的代码如下:

            for (int i = 0; i < 5; i++) {
                string threadName = $"thread_{i}";
                int seconds = 2 + 2 * i;
                var thread = new Thread(delegate ()
                  {
                      WorkOnSemaphore(threadName, seconds);
                  });
                thread.Start();
            }

结果:

 通过结果可以看出,每次只能有2个线程能同时访问,而其他的线程则被阻塞等待。

参考文献:https://docs.microsoft.com/zh-cn/dotnet/standard/threading/semaphore-and-semaphoreslim

原文地址:https://www.cnblogs.com/williamwsj/p/13859555.html