亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#資源池限制實例分析

發布時間:2022-02-14 09:22:44 來源:億速云 閱讀:127 作者:iii 欄目:開發技術

這篇“C#資源池限制實例分析”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“C#資源池限制實例分析”文章吧。

Semaphore、SemaphoreSlim 類

兩者都可以限制同時訪問某一資源或資源池的線程數。

Semaphore 類

這里,先列出 Semaphore 類常用的 API。

其構造函數如下:

構造函數說明
Semaphore(Int32, Int32)初始化 Semaphore 類的新實例,并指定初始入口數和最大并發入口數。
Semaphore(Int32, Int32, String)初始化 Semaphore 類的新實例,并指定初始入口數和最大并發入口數,根據需要指定系統信號燈對象的名稱。
Semaphore(Int32, Int32, String, Boolean)初始化 Semaphore 類的新實例,并指定初始入口數和最大并發入口數,還可以選擇指定系統信號量對象的名稱,以及指定一個變量來接收指示是否創建了新系統信號量的值。

Semaphore 使用純粹的內核時間(kernel-time)方式(等待時間很短),并且支持在不同的進程間同步線程(像Mutex)。

Semaphore 常用方法如下:

方法說明
Close()釋放由當前 WaitHandle占用的所有資源。
OpenExisting(String)打開指定名稱為信號量(如果已經存在)。
Release()退出信號量并返回前一個計數。
Release(Int32)以指定的次數退出信號量并返回前一個計數。
TryOpenExisting(String, Semaphore)打開指定名稱為信號量(如果已經存在),并返回指示操作是否成功的值。
WaitOne()阻止當前線程,直到當前 WaitHandle 收到信號。
WaitOne(Int32)阻止當前線程,直到當前 WaitHandle 收到信號,同時使用 32 位帶符號整數指定時間間隔(以毫秒為單位)。
WaitOne(Int32, Boolean)阻止當前線程,直到當前的 WaitHandle 收到信號為止,同時使用 32 位帶符號整數指定時間間隔,并指定是否在等待之前退出同步域。
WaitOne(TimeSpan)阻止當前線程,直到當前實例收到信號,同時使用 TimeSpan 指定時間間隔。
WaitOne(TimeSpan, Boolean)阻止當前線程,直到當前實例收到信號為止,同時使用 TimeSpan 指定時間間隔,并指定是否在等待之前退出同步域。

示例

我們來直接寫代碼,這里使用 《原子操作 Interlocked》 中的示例,現在我們要求,采用多個線程執行計算,但是只允許最多三個線程同時執行運行。

使用 Semaphore ,有四個個步驟:

new 實例化 Semaphore,并設置最大線程數、初始化時可進入線程數;

使用 .WaitOne(); 獲取進入權限(在獲得進入權限前,線程處于阻塞狀態)。

離開時使用 Release() 釋放占用。

Close() 釋放Semaphore 對象。

《原子操作 Interlocked》 中的示例改進如下:

    class Program
    {
        // 求和
        private static int sum = 0;
        private static Semaphore _pool;

        // 判斷十個線程是否結束了。
        private static int isComplete = 0;
        // 第一個程序
        static void Main(string[] args)
        {
            Console.WriteLine("執行程序");

            // 設置允許最大三個線程進入資源池
            // 一開始設置為0,就是初始化時允許幾個線程進入
            // 這里設置為0,后面按下按鍵時,可以放通三個線程
            _pool = new Semaphore(0, 3);
            for (int i = 0; i < 10; i++)
            {
                Thread thread = new Thread(new ParameterizedThreadStart(AddOne));
                thread.Start(i + 1);
            }
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("任意按下鍵(不要按關機鍵),可以打開資源池");
            Console.ForegroundColor = ConsoleColor.White;
            Console.ReadKey();

            // 準許三個線程進入
            _pool.Release(3);

            // 這里沒有任何意義,就單純為了演示查看結果。
            // 等待所有線程完成任務
            while (true)
            {
                if (isComplete >= 10)
                    break;
                Thread.Sleep(TimeSpan.FromSeconds(1));
            }
            Console.WriteLine("sum = " + sum);

            // 釋放池
            _pool.Close();
            
        }

        public static void AddOne(object n)
        {
            Console.WriteLine($"    線程{(int)n}啟動,進入隊列");
            // 進入隊列等待
            _pool.WaitOne();
            Console.WriteLine($"第{(int)n}個線程進入資源池");
            // 進入資源池
            for (int i = 0; i < 10; i++)
            {
                Interlocked.Add(ref sum, 1);
                Thread.Sleep(TimeSpan.FromMilliseconds(500));
            }
            // 解除占用的資源池
            _pool.Release();
            isComplete += 1;
            Console.WriteLine($"                     第{(int)n}個線程退出資源池");
        }
    }

看著代碼有點多,快去運行一下,看看結果。

示例說明

實例化 Semaphore 使用了new Semaphore(0,3); ,其構造函數原型為

public Semaphore(int initialCount, int maximumCount);

initialCount 表示一開始允許幾個進程進入資源池,如果設置為0,所有線程都不能進入,要一直等資源池放通。

maximumCount 表示最大允許幾個線程進入資源池。

Release() 表示退出信號量并返回前一個計數。這個計數指的是資源池還可以進入多少個線程。

可以看一下下面的示例:

        private static Semaphore _pool;
        static void Main(string[] args)
        {
            _pool = new Semaphore(0, 5);
            _pool.Release(5);
            new Thread(AddOne).Start();
            Thread.Sleep(TimeSpan.FromSeconds(10));
            _pool.Close();
        }

        public static void AddOne()
        {
            _pool.WaitOne();
            Thread.Sleep(1000);
            int count = _pool.Release();
            Console.WriteLine("在此線程退出資源池前,資源池還有多少線程可以進入?" + count);
        }

信號量

前面我們學習到 Mutex,這個類是全局操作系統起作用的。我們從 Mutex 和 Semphore 中,也看到了 信號量這個東西。

信號量分為兩種類型:本地信號量和命名系統信號量。

  • 命名系統信號量在整個操作系統中均可見,可用于同步進程的活動。

  • 局部信號量僅存在于進程內。

當 name 為 null 或者為空時,Mutex 的信號量時局部信號量,否則 Mutex 的信號量是命名系統信號量。

Semaphore 的話,也是兩種情況都有。

如果使用接受名稱的構造函數創建 Semaphor 對象,則該對象將與該名稱的操作系統信號量關聯。

兩個構造函數:

Semaphore(Int32, Int32, String)
Semaphore(Int32, Int32, String, Boolean)

上面的構造函數可以創建多個表示同一命名系統信號量的 Semaphore 對象,并可以使用 OpenExisting 方法打開現有的已命名系統信號量。

我們上面使用的示例就是局部信號量,進程中引用本地 Semaphore 對象的所有線程都可以使用。 每個 Semaphore 對象都是單獨的本地信號量。

SemaphoreSlim類

SemaphoreSlim 跟 Semaphore 有啥關系?

微軟文檔:

SemaphoreSlim 表示對可同時訪問資源或資源池的線程數加以限制的 Semaphore 的輕量替代。

SemaphoreSlim 不使用信號量,不支持進程間同步,只能在進程內使用。

它有兩個構造函數:

構造函數說明
SemaphoreSlim(Int32)初始化 SemaphoreSlim 類的新實例,以指定可同時授予的請求的初始數量。
SemaphoreSlim(Int32, Int32)初始化 SemaphoreSlim 類的新實例,同時指定可同時授予的請求的初始數量和最大數量。

示例

我們改造一下前面 Semaphore 中的示例:

    class Program
    {
        // 求和
        private static int sum = 0;
        private static SemaphoreSlim _pool;

        // 判斷十個線程是否結束了。
        private static int isComplete = 0;
        static void Main(string[] args)
        {
            Console.WriteLine("執行程序");

            // 設置允許最大三個線程進入資源池
            // 一開始設置為0,就是初始化時允許幾個線程進入
            // 這里設置為0,后面按下按鍵時,可以放通三個線程
            _pool = new SemaphoreSlim(0, 3);
            for (int i = 0; i < 10; i++)
            {
                Thread thread = new Thread(new ParameterizedThreadStart(AddOne));
                thread.Start(i + 1);
            }

            Console.WriteLine("任意按下鍵(不要按關機鍵),可以打開資源池");
            Console.ReadKey();
            // 
            _pool.Release(3);

            // 這里沒有任何意義,就單純為了演示查看結果。
            // 等待所有線程完成任務
            while (true)
            {
                if (isComplete >= 10)
                    break;
                Thread.Sleep(TimeSpan.FromSeconds(1));
            }
            Console.WriteLine("sum = " + sum);
            // 釋放池
        }

        public static void AddOne(object n)
        {
            Console.WriteLine($"    線程{(int)n}啟動,進入隊列");
            // 進入隊列等待
            _pool.Wait();
            Console.WriteLine($"第{(int)n}個線程進入資源池");
            // 進入資源池
            for (int i = 0; i < 10; i++)
            {
                Interlocked.Add(ref sum, 1);
                Thread.Sleep(TimeSpan.FromMilliseconds(200));
            }
            // 解除占用的資源池
            _pool.Release();
            isComplete += 1;
            Console.WriteLine($"                     第{(int)n}個線程退出資源池");
        }
    }

SemaphoreSlim 不需要 Close()

兩者在代碼上的區別是就這么簡單。

區別

如果使用下面的構造函數實例化 Semaphor(參數name不能為空),那么創建的對象在整個操作系統內都有效。

public Semaphore (int initialCount, int maximumCount, string name);

Semaphorslim 則只在進程內內有效。

SemaphoreSlim 類不會對 WaitWaitAsync 和 Release 方法的調用強制執行線程或任務標識。

而 Semaphor 類,會對此進行嚴格監控,如果對應調用數量不一致,會出現異常。

此外,如果使用 SemaphoreSlim(Int32 maximumCount) 構造函數來實例化 SemaphoreSlim 對象,獲取其 CurrentCount 屬性,其值可能會大于 maximumCount。 編程人員應負責確保調用一個 Wait 或 WaitAsync 方法,便調用一個 Release。

這就好像筆筒里面的筆,沒有監控,使用這使用完畢后,都應該將筆放進去。如果原先有10支筆,每次使用不放進去,或者將別的地方的筆放進去,那么最后數量就不是10了。

C#資源池限制實例分析

以上就是關于“C#資源池限制實例分析”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

万山特区| 黔东| 香格里拉县| 石楼县| 红安县| 南乐县| 仪征市| 鸡泽县| 临夏县| 邻水| 兴国县| 扎鲁特旗| 手游| 内江市| 丽水市| 德钦县| 阳城县| 仁怀市| 乌拉特前旗| 措美县| 突泉县| 义马市| 萨迦县| 岑巩县| 健康| 古交市| 巴林左旗| 全州县| 永仁县| 邻水| 兴义市| 永胜县| 白朗县| 贵阳市| 大关县| 肇庆市| 竹山县| 宝山区| 藁城市| 花垣县| 昔阳县|