2019年3月4日 星期一

C# 執行緒(Thread)的Mutex及Semaphore探討

Mutex
作用在不同Process之間,同一時間內只授予一個Thread在共享資源的獨佔訪問。就好像是馬桶一樣,一次只能有一個人用,下一個想用馬桶的人只能等待。
 Semaphore
限制在同一時間內,允許訪問共享資源的Thread數量上限。就像百貨公司的廁所一樣,假設共有10間,一次最多就只能10個人同時上廁所,其餘想上廁所的人就得排隊等待。

以下是 Mutex範例:

using System;
using System.Threading;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            /** *******************
            * Thread的Mutex機制
            * ********************/
            string mutexName = "互斥量";
            using (var mutex = new Mutex(false, mutexName))
            {
                if (mutex.WaitOne(TimeSpan.FromSeconds(5), false))
                {
                    Console.WriteLine("占用一下");
                    Console.ReadLine();
                    mutex.ReleaseMutex();
                }
                else
                {
                    Console.WriteLine("我搶不到");
                }
            }
            Console.WriteLine("Hello World!");
            Console.ReadLine();
        }
    }
}

同時執行兩個Process時,第一個Process會看到占用一下,第二個Process會看到我搶不到,


以下是 Semaphore範例:

using System;
using System.Threading;

namespace ConsoleApp1
{
    class Program
    {
        static SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(3);

        /// <summary>
        /// 在上廁所
        /// </summary>
        /// <param name="seconds"></param>
        static void Toilet(int seconds)
        {
            Console.WriteLine($"{Thread.CurrentThread.Name}等待中");
            _semaphoreSlim.Wait();
            Console.WriteLine($"{Thread.CurrentThread.Name}上廁所");
            Thread.Sleep(TimeSpan.FromSeconds(seconds));
            Console.WriteLine($"{Thread.CurrentThread.Name}上完了!");
            _semaphoreSlim.Release();
        }

        static void Main(string[] args)
        {
            // 假设廁所只有3個,但有5人要上廁所,所以有2位需要等待
            for (int i = 0; i < 5; i++)
            {
                Thread t = new Thread(() => {
                    Toilet(new Random().Next(2, 4));
                });
                t.Name = $"t{i}";
                t.Start();
            }

            Console.ReadKey();
        }
    }
}

執行結果如下:
廁所有三間,一開始 t0, t1, t4先上廁所,等 t0上完廁所了,t2才進入上廁所狀態。

沒有留言:

張貼留言