欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#多線程系列之多階段并行線程

 更新時(shí)間:2022年02月13日 16:07:08   作者:癡者工良  
本文詳細(xì)講解了C#多線程的多階段并行線程,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

前言

這一篇,我們將學(xué)習(xí)用于實(shí)現(xiàn)并行任務(wù)、使得多個(gè)線程有序同步完成多個(gè)階段的任務(wù)。

應(yīng)用場(chǎng)景主要是控制 N 個(gè)線程(可隨時(shí)增加或減少執(zhí)行的線程),使得多線程在能夠在 M 個(gè)階段中保持同步。

線程工作情況如下:

我們接下來(lái) 將學(xué)習(xí)C# 中的 Barrier ,用于實(shí)現(xiàn)并行協(xié)同工作。

Barrier 類(lèi)

使多個(gè)任務(wù)能夠采用并行方式依據(jù)某種算法在多個(gè)階段中協(xié)同工作,使多個(gè)線程(稱(chēng)為“參與者” )分階段同時(shí)處理算法。

可以使多個(gè)線程(稱(chēng)為“參與者” )分階段同時(shí)處理算法。(注意算法這個(gè)詞)

每個(gè)參與者完成階段任務(wù)后后將被阻止繼續(xù)執(zhí)行,直至所有參與者都已達(dá)到同一階段。

Barrier 的構(gòu)造函數(shù)如下:

構(gòu)造函數(shù)說(shuō)明
Barrier(Int32)初始化 Barrier 類(lèi)的新實(shí)例。
Barrier(Int32, Action)初始化 Barrier 類(lèi)的新實(shí)例。

其中一個(gè)構(gòu)造函數(shù)定義如下:

public Barrier (int participantCount, Action<Barrier> postPhaseAction);

participantCount :處于的線程數(shù)量,大于0并且小于32767。

postPhaseAction :在每個(gè)階段后執(zhí)行 Action(委托)。

屬性和方法

在還沒(méi)有清楚這個(gè)類(lèi)有什么作用前,我們來(lái)看一下這個(gè)類(lèi)的常用屬性和方法。

大概了解 Barrier 有哪些常用屬性和方法后,我們開(kāi)始編寫(xiě)示例代碼。

屬性:

屬性說(shuō)明
CurrentPhaseNumber獲取屏障的當(dāng)前階段的編號(hào)。
ParticipantCount獲取屏障中參與者的總數(shù)。
ParticipantsRemaining獲取屏障中尚未在當(dāng)前階段發(fā)出信號(hào)的參與者的數(shù)量。

方法:

方法說(shuō)明
AddParticipant()通知 Barrier,告知其將會(huì)有另一個(gè)參與者。
AddParticipants(Int32)通知 Barrier,告知其將會(huì)有多個(gè)其他參與者。
RemoveParticipant()通知 Barrier,告知其將會(huì)減少一個(gè)參與者。
RemoveParticipants(Int32)通知 Barrier,告知其將會(huì)減少一些參與者。
SignalAndWait()發(fā)出參與者已達(dá)到屏障并等待所有其他參與者也達(dá)到屏障。
SignalAndWait(CancellationToken)發(fā)出參與者已達(dá)到屏障的信號(hào),并等待所有其他參與者達(dá)到屏障,同時(shí)觀察取消標(biāo)記。
SignalAndWait(Int32)發(fā)出參與者已達(dá)到屏障的信號(hào),并等待所有其他參與者也達(dá)到屏障,同時(shí)使用 32 位帶符號(hào)整數(shù)測(cè)量超時(shí)。
SignalAndWait(Int32, CancellationToken)發(fā)出參與者已達(dá)到屏障的信號(hào),并等待所有其他參與者也達(dá)到屏障,使用 32 位帶符號(hào)整數(shù)測(cè)量超時(shí),同時(shí)觀察取消標(biāo)記。
SignalAndWait(TimeSpan)發(fā)出參與者已達(dá)到屏障的信號(hào),并等待所有其他參與者也達(dá)到屏障,同時(shí)使用 TimeSpan 對(duì)象測(cè)量時(shí)間間隔。
SignalAndWait(TimeSpan, CancellationToken)發(fā)出參與者已達(dá)到屏障的信號(hào),并等待所有其他參與者也達(dá)到屏障,使用 TimeSpan 對(duì)象測(cè)量時(shí)間間隔,同時(shí)觀察取消標(biāo)記。

Barrier 翻譯屏障,前面所說(shuō)的 “階段”,在文檔中稱(chēng)為屏障,官方有一些例子和實(shí)踐場(chǎng)景:

https://docs.microsoft.com/zh-cn/dotnet/standard/threading/barrier?view=netcore-3.1

https://docs.microsoft.com/zh-cn/dotnet/standard/threading/how-to-synchronize-concurrent-operations-with-a-barrier?view=netcore-3.1

本文的教程比較簡(jiǎn)單,你可以先看本教程,再去看看官方示例。

示例

假設(shè)有個(gè)比賽,一個(gè)有三個(gè)環(huán)節(jié),有三個(gè)小組參加比賽。

比賽有三個(gè)環(huán)節(jié),小組完成一個(gè)環(huán)節(jié)后,可以去等待區(qū)休息,等待其他小組也完成比賽后,開(kāi)始進(jìn)行下一個(gè)環(huán)節(jié)的比賽。

示例如下:

new Barrier(int,Action) 設(shè)置有多少線程參與,Action 委托設(shè)置每個(gè)階段完成后執(zhí)行哪些動(dòng)作。

.SignalAndWait() 阻止當(dāng)前線程繼續(xù)往下執(zhí)行;直到其他完成也執(zhí)行到此為止。

    class Program
    {
        // Barrier(Int32, Action)
        private static Barrier barrier = new Barrier(3, b =>
                            Console.WriteLine($"\n第 {b.CurrentPhaseNumber + 1} 環(huán)節(jié)的比賽結(jié)束,請(qǐng)?jiān)u分!"));

        static void Main(string[] args)
        {
            // Random 模擬每個(gè)小組完成一個(gè)環(huán)節(jié)比賽需要的時(shí)間
            Thread thread1 = new Thread(() => DoWork("第一小組", new Random().Next(2, 10)));
            Thread thread2 = new Thread(() => DoWork("第二小組", new Random().Next(2, 10)));
            Thread thread3 = new Thread(() => DoWork("第三小組", new Random().Next(2, 10)));

            // 三個(gè)小組開(kāi)始比賽
            thread1.Start();
            thread2.Start();
            thread3.Start();


            Console.ReadKey();
        }
        static void DoWork(string name, int seconds)
        {
            // 第一環(huán)節(jié)
            Console.WriteLine($"\n{name}:開(kāi)始進(jìn)入第一環(huán)節(jié)比賽");
            Thread.Sleep(TimeSpan.FromSeconds(seconds));    // 模擬小組完成環(huán)節(jié)比賽需要的時(shí)間
            Console.WriteLine($"\n    {name}:完成第一環(huán)節(jié)比賽,等待其它小組");
            // 小組完成階段任務(wù),去休息等待其它小組也完成比賽
            barrier.SignalAndWait();

            // 第二環(huán)節(jié)
            Console.WriteLine($"\n        {name}:開(kāi)始進(jìn)入第二環(huán)節(jié)比賽");
            Thread.Sleep(TimeSpan.FromSeconds(seconds));
            Console.WriteLine($"\n        {name}:完成第二環(huán)節(jié)比賽,等待其它小組\n");
            barrier.SignalAndWait();


            // 第三環(huán)節(jié)
            Console.WriteLine($"\n        {name}:開(kāi)始進(jìn)入第三環(huán)節(jié)比賽");
            Thread.Sleep(TimeSpan.FromSeconds(seconds));
            Console.WriteLine($"\n        {name}:完成第三環(huán)節(jié)比賽,等待其它小組\n");
            barrier.SignalAndWait();
        }
    }

上面的示例中,每個(gè)線程都使用了 DoWork() 這個(gè)方法去中相同的事情,當(dāng)然也可以設(shè)置多個(gè)線程執(zhí)行不同的任務(wù),但是必須保證每個(gè)線程都具有相同數(shù)量的 .SignalAndWait(); 方法。

當(dāng)然 SignalAndWait() 可以設(shè)置等待時(shí)間,如果其他線程遲遲沒(méi)有到這一步,那就繼續(xù)運(yùn)行??梢员苊馑梨i等問(wèn)題。

到目前,只使用了 SignalAndWait() ,我們繼續(xù)學(xué)習(xí)一下 Barrier 類(lèi)的其他方法。

新的示例

Barrier.AddParticipant():添加參與者;

Barrier.RemoveParticipant():移除參與者;

這里繼續(xù)使用第二節(jié)的示例。

因?yàn)檫@是比賽,老是等待其他小組,會(huì)使得比賽進(jìn)行比較慢。

新的規(guī)則:不必等待最后一名,當(dāng)環(huán)節(jié)只剩下最后一名時(shí)為完成時(shí),其它小組可以立即進(jìn)行下一個(gè)環(huán)節(jié)的比賽。

? 當(dāng)然,最后一名小組,有權(quán)利繼續(xù)完成比賽。

修改第二小節(jié)的代碼,在 Main 內(nèi)第一行加上 barrier.RemoveParticipant();。

        static void Main(string[] args)
        {
            barrier.RemoveParticipant();
            ... ...

試著再運(yùn)行一下。

說(shuō)明

SignalAndWait() 的 重載比較多,例如 SignalAndWait(CancellationToken),這里筆者先不講解此方法如何使用。等到寫(xiě)到后面的異步(Task),讀者學(xué)到相關(guān)的知識(shí)點(diǎn),我們?cè)龠^(guò)一次復(fù)習(xí),這樣由易到難,自然水到渠成。

Barrier 適合用于同時(shí)執(zhí)行相同流程的工作,因?yàn)楣ぷ鲀?nèi)容是相同的,便于協(xié)同。工作流有可能用得上吧。

但是 Barrier 更加適合用于算法領(lǐng)域,可以參考:https://devblogs.microsoft.com/pfxteam/parallel-merge-sort-using-barrier/

到此這篇關(guān)于C#多線程系列之多階段并行線程的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C#定制Excel界面并實(shí)現(xiàn)與數(shù)據(jù)庫(kù)交互的方法

    C#定制Excel界面并實(shí)現(xiàn)與數(shù)據(jù)庫(kù)交互的方法

    這篇文章主要介紹了C#定制Excel界面并實(shí)現(xiàn)與數(shù)據(jù)庫(kù)交互的方法的相關(guān)資料,需要的朋友可以參考下
    2015-11-11
  • C#中矩形數(shù)組的定義和元素訪問(wèn)

    C#中矩形數(shù)組的定義和元素訪問(wèn)

    矩形數(shù)組是指由相同數(shù)據(jù)類(lèi)型的元素按照行和列組成的二維數(shù)組,可以使用索引訪問(wèn)矩形數(shù)組中的單個(gè)元素,也可以使用循環(huán)結(jié)構(gòu)遍歷矩形數(shù)組中的所有元素,此外,我們還需要注意不要修改矩形數(shù)組的維度,避免使用矩形數(shù)組造成內(nèi)存占用過(guò)高等問(wèn)題
    2024-01-01
  • C#實(shí)現(xiàn)將窗體固定在顯示器的左上角且不能移動(dòng)的方法

    C#實(shí)現(xiàn)將窗體固定在顯示器的左上角且不能移動(dòng)的方法

    這篇文章主要介紹了C#實(shí)現(xiàn)將窗體固定在顯示器的左上角且不能移動(dòng)的方法,涉及C#窗體固定操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-08-08
  • 淺談C#2.0泛型中的變化:default關(guān)鍵字

    淺談C#2.0泛型中的變化:default關(guān)鍵字

    下面就詳細(xì)的說(shuō)明一下。之所以會(huì)用到default關(guān)鍵字,是因?yàn)樾枰诓恢李?lèi)型參數(shù)為值類(lèi)型還是引用類(lèi)型的情況下,為對(duì)象實(shí)例賦初值
    2013-09-09
  • C#類(lèi)的多態(tài)性詳解

    C#類(lèi)的多態(tài)性詳解

    這篇文章主要為大家詳細(xì)介紹了C#類(lèi)的多態(tài)性,主要有兩種:一是編譯時(shí)的多態(tài)性,二是運(yùn)行時(shí)的多態(tài)性,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2015-10-10
  • C#判斷字符串是否是int/double(實(shí)例)

    C#判斷字符串是否是int/double(實(shí)例)

    本文主要分享了C#判斷字符串是否是int/double的具體實(shí)例,具有一定的參考價(jià)值,需要的朋友一起來(lái)看下吧
    2016-12-12
  • C#中動(dòng)態(tài)顯示當(dāng)前系統(tǒng)時(shí)間的實(shí)例方法

    C#中動(dòng)態(tài)顯示當(dāng)前系統(tǒng)時(shí)間的實(shí)例方法

    想在網(wǎng)頁(yè)中動(dòng)態(tài)地顯示當(dāng)前系統(tǒng)的時(shí)間,找了好多,不過(guò)都是一些停在那里不動(dòng)的。。。不過(guò)皇天不負(fù)有心人,終于讓我找到了
    2013-05-05
  • c#循環(huán)左移字符示例

    c#循環(huán)左移字符示例

    這篇文章主要介紹了c#循環(huán)左移字符示例,需要的朋友可以參考下
    2014-04-04
  • 詳解C#如何判斷字符串的顯示寬度

    詳解C#如何判斷字符串的顯示寬度

    這篇文章主要為大家詳細(xì)介紹了C#判斷字符串的顯示寬度的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下
    2023-11-11
  • 聊聊Unity自定義組件之序列幀播放組件問(wèn)題

    聊聊Unity自定義組件之序列幀播放組件問(wèn)題

    由于最近的項(xiàng)目中需要用到大量的序列幀動(dòng)畫(huà)以及邏輯處理,本來(lái)想用Unity自帶的Animation組件來(lái)實(shí)現(xiàn)的,但由于甲方需求一再變更,需要處理的邏輯太多,為了方便修改和拓展,所以就根據(jù)自己項(xiàng)目的需求自定義了一個(gè)序列幀播放組件來(lái)輔助開(kāi)發(fā)
    2022-01-01

最新評(píng)論