一文帶你了解.Net信號量


在這里插入圖片描述
本文主要講解.Net基於Semaphore帶大家了解信號量


信號量舉例

大家去銀行去銀行取錢,互斥鎖管理的時一個櫃台是否正在處理業務,而信號量管理的是整個櫃台是否正在處理業務,每當有一個櫃台處理完成之后,A大堂經理則進行叫號喊下一位進行處理業務,B大堂經理則對進來的客戶進行接待,當櫃台全部都在辦理業務時,新來的辦理業務者則需要進行等待

信號量的基礎概念

信號量是一個具有特殊用途的線程同步對象,相比互斥鎖只有兩個狀態(未被獲取/已被獲取),信號量內部使用一個數值記錄可用的數量,每個線程可以通過增加和減少數量兩個操作進行同步。當執行減少數量操作時,如果減少的數量大於現有的數量,則線程需要進入等待狀態,知道其他線程執行增加數量操作后數量不少於減少的數量為止。

信號量和互斥鎖的區別

互斥鎖釋放鎖的線程必須是獲取鎖的線程,而信號量增加數量和減少數量可以是不通

操作系統的區別

  • windows系統中信號量對象從CreateSemaphoreEx函數創建,減少數量是通過WaitForMultipObjectsEx函數,增加數量時通過ReleaseSemaphoehanshu, 由於接口限制,減少數量時只能減少1,而增加數量則可以使用自定義數量。
  • linux系統中有Net Core的內部結構模擬實現。
  • 和System.Threading.Mutex一樣,Semaphore可以進行使用參數命名來控制跨進程使用(注意,只支持window平台,其他平台使用會拋出異常)

代碼事例

 public class Program
    {
        //第一個參數代表初始數量,第二個參數代表最大數量,第三個參數代表跨進程名稱(本文未演示)
        private static readonly Semaphore _sema = new(0, 10);

        /// <summary>
        /// 執行函數
        /// </summary>
        /// <param name="args"></param>
        public static void Main(string[] args)
        {
            for (var i = 0; i < 6; ++i)
            {
                var thread = new Thread(Work);
                thread.Start();
            }
            while (true)
            {
                //執行增加數量,增加值為5
                _sema.Release(5);
                Thread.Sleep(1000 * 10);
            }
        }

        public static void Work()
        {
            while (true)
            {
                //執行減少操作,減少值為1
                _sema.WaitOne();
                Console.WriteLine($"當前時間為:{DateTime.Now:yyyy-MM-dd HH:mm:ss:fff}");
                Console.WriteLine($"當前線程Id為:{Thread.CurrentThread.ManagedThreadId}");
                Console.WriteLine("************************");
            }
        }
    }

輕量信號量

輕量信號量不支持跨進程使用,如果不需要使用跨進程,可以使用SemaphoreSlim來代替Semaphore

public class SemaphoreSlimDemo
    {
        private static readonly SemaphoreSlim _semaphoreSlim = new(0, 10);

        public static void Wrok()
        {
            while (true)
            {
                _semaphoreSlim.Wait();
                System.Console.WriteLine("do work");
            }
        }

        /// <summary>
        ///  執行函數
        /// </summary>
        public static void Run()
        {
            for (var i = 0; i < 6; i++)
            {
                var thread = new Thread(Wrok)
                {
                    IsBackground = true
                };
                thread.Start();
            }
            while (true)
            {
                _semaphoreSlim.Release(2);
                Thread.Sleep(1000);
            }
        }
    }

本文基於.Net Core底層入門總結內容

如有哪里講得不是很明白或是有錯誤,歡迎指正
如您喜歡的話不妨點個贊收藏一下吧🙂


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM