溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C#中怎么實(shí)現(xiàn)并行編程

發(fā)布時(shí)間:2021-07-07 15:15:46 來(lái)源:億速云 閱讀:341 作者:Leah 欄目:大數(shù)據(jù)

C#中怎么實(shí)現(xiàn)并行編程,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

并行的相關(guān)實(shí)戰(zhàn)

說(shuō)到并行,就需要先說(shuō)下.NET FX4中引入的Task Parallel Library(任務(wù)并行庫(kù)),簡(jiǎn)稱TPL。TPL主要覆蓋了三大使用場(chǎng)景,數(shù)據(jù)并行、任務(wù)并行和流水線,TPL以其高度的封裝特性,隱藏了并行編程里復(fù)雜的處理,使得開(kāi)發(fā)人員可以以較低的門(mén)檻進(jìn)行并行編程。

數(shù)據(jù)并行

這種場(chǎng)景在于有大量數(shù)據(jù)需要處理,而且對(duì)每一份數(shù)據(jù)都要執(zhí)行的同樣的操作。

C#中怎么實(shí)現(xiàn)并行編程

任務(wù)并行

有很多相對(duì)獨(dú)立的不同操作,或者可以分割成多個(gè)子任務(wù)但彼此之間是獨(dú)立的,就可以通過(guò)任務(wù)并行來(lái)發(fā)揮并行化的優(yōu)勢(shì)
C#中怎么實(shí)現(xiàn)并行編程
 

流水線

流水線是以上兩種場(chǎng)景的結(jié)合,這個(gè)也是最復(fù)雜最難處理的場(chǎng)景,因?yàn)檫@里面涉及到多個(gè)并發(fā)的任務(wù)進(jìn)行協(xié)調(diào)處理。

此場(chǎng)景,奈何小編理解的不是很好,所以不敢亂寫(xiě),多方查找資料,找到了oschina上的一篇文章。

流水線技術(shù),指的是允許一個(gè)機(jī)器周期內(nèi)的計(jì)算機(jī)各處理步驟重疊進(jìn)行。特別是,當(dāng)執(zhí)行一條指令時(shí),可以讀取下一條指令,也就意味著,在任何一個(gè)時(shí)刻可以有不止一條指令在“流水線”上,每條指令處在不同的執(zhí)行階段。這樣,即便讀取和執(zhí)行每條指令的時(shí)間保持不變,而計(jì)算機(jī)的總的吞吐量提高了。

C#中怎么實(shí)現(xiàn)并行編程

原文地址:https://my.oschina.net/u/3374461/blog/1930305

System.Threading.Tasks.Parallel類

雖然Parallel類在System.Threading.Tasks命名空間下,但是創(chuàng)建并行代碼不一定要直接使用Task類的實(shí)例,我們可以直接使用Parallel靜態(tài)類所提供的方法。

Parallel.For:為固定數(shù)目的獨(dú)立For循環(huán)迭代提供了負(fù)載均衡式的并行執(zhí)行

Parallel.For(0, 5, i =>{    Console.WriteLine("the number is", i);});

Parallel.Foreach:為固定數(shù)目的獨(dú)立ForEach循環(huán)迭代提供了負(fù)載均衡式的并行執(zhí)行。這個(gè)方法支持自定義分區(qū)器(Partitioner),以使得我們可以完全掌控?cái)?shù)據(jù)分發(fā)。

string[] letters = new string[] {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M"};Parallel.ForEach(letters, i => Console.WriteLine("letter is " + i));

Parallel.Invoke:為給定的獨(dú)立任務(wù)提供了負(fù)載均衡式的并行執(zhí)行,接下來(lái)會(huì)重點(diǎn)討論這個(gè)方法。

Parallel.Invoke

這個(gè)方法很實(shí)用,也很簡(jiǎn)單。

以下代碼可以返回void的無(wú)參數(shù)方法:

Parallel.Invoke(Method1(), Method2(), Method3(), Method4());
通過(guò)Lambda表達(dá)式運(yùn)行:
Parallel.Invoke(() => Method1(), () => Method2(), () => Method3(), () => Method4());

通過(guò)Lambda表達(dá)式和匿名類型來(lái)運(yùn)行:

Parallel.Invoke(() =>{    Method1();    // Do something}, () =>{    Method2();    // Do something },  () => {     Method3();     // Do something },  () => {     Method4();     // Do something});

以上代碼需要并行執(zhí)行四個(gè)方法,但是如果空余邏輯內(nèi)核不足四個(gè)或者根本就沒(méi)有四個(gè)邏輯內(nèi)核,這四個(gè)方法是不能并發(fā)執(zhí)行的。因此在理想情況下,正好有至少四個(gè)空余邏輯內(nèi)核時(shí),我們就可以并行執(zhí)行這四個(gè)方法了。

這四個(gè)方法,我們無(wú)法準(zhǔn)確的預(yù)測(cè)其執(zhí)行順序,因?yàn)檫@一切是由底層的邏輯會(huì)根據(jù)運(yùn)行時(shí)的現(xiàn)有可用資源創(chuàng)建出最合適的執(zhí)行計(jì)劃。當(dāng)然TPL依然有機(jī)制保證方法的順序執(zhí)行,這個(gè)以后我們?cè)儆懻摗?/p>

Parallel.Invoke最大的優(yōu)勢(shì)就是簡(jiǎn)單,但是并不能因?yàn)樗?jiǎn)單,就不分場(chǎng)合的使用,事實(shí)上,我們需要在某些場(chǎng)景下權(quán)衡使用。

  • 如果這四個(gè)方法的執(zhí)行時(shí)間不一致,那么就需要根據(jù)最長(zhǎng)的執(zhí)行時(shí)間才能返回控制,這就可能造成一些邏輯內(nèi)核處于閑置狀態(tài)。所以我們需要預(yù)測(cè)一下大致的執(zhí)行時(shí)間,如果時(shí)間過(guò)長(zhǎng),那么就要認(rèn)真考慮是否真的需要使用這個(gè)方法。

  • 其擴(kuò)展性很差,因?yàn)樗荒苷{(diào)用固定數(shù)目的邏輯內(nèi)核,剩余內(nèi)核就會(huì)一直處于閑置狀態(tài)。

  • 方法之間的交互極其困難,極易產(chǎn)生Bug,當(dāng)然這是并行編程的常見(jiàn)問(wèn)題,TPL也考慮到了這點(diǎn),也有足夠機(jī)制解決這個(gè)問(wèn)題。

  • 如果其中某個(gè)方法有了異常,捕捉異常會(huì)很困難,所以需要大家在相應(yīng)的被調(diào)用方法里編寫(xiě)足夠的日志。

  • 小編在以前的使用中還遇到了內(nèi)存溢出的異常,這些也會(huì)在以后的文章中說(shuō)明其原因以及解決方法。

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI