黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

.NET4.0并行計算技術(shù)基礎(chǔ)(7)

系統(tǒng) 2025 0

呵呵,越到國慶反而越忙,好多天沒更新了,工作第一天,貼出一篇新文。
金旭亮
2009.10.9
=======================================
.NET4.0并行計算技術(shù)基礎(chǔ)(7)
=========================================

19.3.4 任務(wù)并行庫原理初探

在上一小節(jié)中,我們看到只需簡單地調(diào)用 Parallel 類中的一些靜態(tài)方法,就可以讓代碼并行執(zhí)行。您一定會對任務(wù)并行庫的強(qiáng)大功能有了很深的印象,一些喜歡刨根問底的讀者可能會問:
任務(wù)并行庫怎樣實現(xiàn)代碼的并行執(zhí)行?
任務(wù)并行庫的底層技術(shù)細(xì)節(jié)很復(fù)雜,要介紹它超出了本書的范疇,然而,對其工作原理作一個介紹是可能的,了解這些知識,對于開發(fā)并行程序而言是很有益的。

1 并行指令的生成

軟件工程師使用 Paralllel 類編寫的并行算法,經(jīng)過編譯器的處理,會全部轉(zhuǎn)換為對 Task 類相應(yīng)方法和屬性的調(diào)用指令,這些指令被保存到編譯好的程序集中。
Task 類的實例代表一個可以被并行執(zhí)行的任務(wù), 任務(wù)(而不是線程!)是 TPL 實現(xiàn)并行計算的基本單位。

2 任務(wù)并行庫的工作原理

任務(wù)由線程負(fù)責(zé)執(zhí)行,為了獲取較高的性能, TPL 使用線程池中的線程,并且使用了一個與線程池直接集成的“ 任務(wù)調(diào)度器( Task Scheduler ”來負(fù)責(zé)分派工作任務(wù)給線程, 這個調(diào)度器使用的任務(wù)分派策略稱為“ Work-stealing ”。
19 ? 16 所示,線程池中的每個線程都擁有一個專有的(本地的)任務(wù)隊列,當(dāng)線程創(chuàng)建任務(wù)(即 Task 類的實例)時,默認(rèn)設(shè)置下,這些任務(wù)被放入了線程本地工作隊列中。
如果任務(wù)本身是通過調(diào)用 ThreadPool.QueueUserWorkItem() 添加的,則此任務(wù)會被添加到一個全局隊列( global queue )中,這一全局隊列就是 19 ? 16 中所示的“線程池任務(wù)隊列”。
以下是任務(wù)調(diào)度器實現(xiàn)任務(wù)調(diào)度的基本過程:
當(dāng)任務(wù)調(diào)度器開始分派任務(wù)時,它先檢查一下創(chuàng)建此任務(wù)的線程是不是線程池中的線程(這種線程擁有一個本地的任務(wù)隊列),如果不是,此任務(wù)被加入到線程池全局任務(wù)隊列中,如果是,任務(wù)調(diào)度器檢查此任務(wù)是否設(shè)置了 TaskCreationOptions.PreferFairness 標(biāo)記,如果設(shè)置了,則此任務(wù)被加入到線程池全局任務(wù)隊列中,否則,還是被放入到線程的本地隊列中。
當(dāng)一個線程開始執(zhí)行時,它優(yōu)先搜索自己的專有任務(wù)隊列,當(dāng)此隊列為空時,它才會去搜索全局任務(wù)隊列。由此可見,這種調(diào)度策略實際上是其于優(yōu)先級的,本地工作隊列比全局隊列擁有更高的優(yōu)先級。
上述這種默認(rèn)的調(diào)度策略適用于絕大多數(shù)情況,但不可能是所有的情況,如果需要對線程本地隊列和線程池全局隊列中的任務(wù)一視同仁,在不改變調(diào)度策略的情況下(這個策略是由 .NET 為線程池所提供的默認(rèn)調(diào)度器實現(xiàn)的,不可改),可以通過將需要 一視同仁 Task 任務(wù)直接放到線程池全局隊列而不是線程本地隊列中實現(xiàn),其具體的實現(xiàn)方法就是在創(chuàng)建任務(wù)時,設(shè)置它的 TaskCreationOptions.PreferFairness 標(biāo)記。
提示:
如果并行執(zhí)行是通過 Parallel 類的 Invoke For ForEach 方法啟動的,則不能為其指定 TaskCreationOptions.PreferFairness 標(biāo)記,只有在顯式創(chuàng)建 Task 類的代碼中可以設(shè)置此標(biāo)記。下一小節(jié)將介紹如何直接使用 Task 類進(jìn)行基于“任務(wù)”的并行編程。
下面對任務(wù)并行庫的工作原理作一個小結(jié)。
簡單地說: 線程就是 工人 ,它負(fù)責(zé)執(zhí)行 任務(wù) ,任務(wù)由任務(wù)調(diào)度器負(fù)責(zé)分配。
任務(wù)調(diào)度器具有很強(qiáng)的智能性,它能自動協(xié)調(diào)各個任務(wù)的分配,不讓 的線程 忙死 的線程 閑死 。從線程的角度看,由于有任務(wù)調(diào)度器的公平管理,所有線程都是 團(tuán)結(jié)互助 雷鋒
將線程之間合作的工作從線程自身的職責(zé)中 剝離 出來,交由任務(wù)調(diào)度器來統(tǒng)一協(xié)調(diào)管理,這是 .NET 4.0 并行計算任務(wù)庫設(shè)計的一個關(guān)鍵點。如果讓線程自身來負(fù)責(zé)處理工作任務(wù)的合理分配,必然會在線程函數(shù)內(nèi)增加同步的代碼,這會讓整個軟件系統(tǒng)變得復(fù)雜和難于調(diào)試。
我們可以適當(dāng)?shù)貙? TPL 的這種設(shè)計思想引申到社會生活領(lǐng)域:如果將線程比喻為 政府官員 ,那么,任務(wù)調(diào)度器就可以看成是一種 制度 ,正是在 制度 的制約之下, 官員 才可能廉潔公正。
在現(xiàn)實社會中,指望貪官他們 良心 發(fā)現(xiàn)而自己 金盆洗手 是不現(xiàn)實的,必須建立起一種有效的制度,讓所有官員都置于強(qiáng)有力的監(jiān)督之下, 貪污 的行為自然會受到極大的制約。這是題外話了。
在下一小節(jié)中,我們將開始深入地了解 Task 類。

19.3.5 任務(wù)的創(chuàng)建與任務(wù)的狀態(tài)

1 創(chuàng)建任務(wù)

19.3.3 節(jié)中,我們介紹了使用 Parallel 類的幾個靜態(tài)方法(如 Invoke For )進(jìn)行并行編程的基本方法,在 19.3.4 節(jié)中,我們又知道了實際上 Parallel 類的功能是通過 Task 類實現(xiàn)的,因此,如果我們需要對任務(wù)的執(zhí)行方式有更多的控制,可以直接基于 Task 對象編程而非使用 Parallel 類的靜態(tài)方法。
進(jìn)行并行編程的第一步,是創(chuàng)建一個任務(wù)對象。最簡單的方法就是直接使用 new 關(guān)鍵字創(chuàng)建 Task 對象。 Task 類的構(gòu)造函數(shù)有多個重載形式,我們逐個介紹其含義和用途:
public Task(Action action);
上述構(gòu)造函數(shù)創(chuàng)建一個 Task 對象,并且讓其關(guān)聯(lián)一個任務(wù)函數(shù)(由 action 參數(shù)引用),當(dāng) Task 對象被線程執(zhí)行時,此函數(shù)被調(diào)用。
public Task(Action<object> action, object state);
這一構(gòu)造函數(shù)的第 2 個參數(shù)用于向任務(wù)函數(shù)傳送附加信息,這些附加信息其實就是任務(wù)函數(shù)調(diào)用時的實參。
public Task(Action action, TaskCreationOptions creationOptions);
這一構(gòu)造函數(shù)多了一個 TaskCreationOptions 類型的參數(shù),此參數(shù)用于設(shè)置任務(wù)的屬性標(biāo)記,上一小節(jié)說過,默認(rèn)情況下新建的任務(wù)會放在創(chuàng)建它的線程 [1] 的本地隊列中,如果希望將任務(wù)放入線程池的全局隊列中,可以向此構(gòu)造函數(shù)傳入“ TaskCreationOptions.PreferFairness ”值。


[1] 假設(shè)此線程是線程池中的線程
public Task(Action<object> action, object state,
TaskCreationOptions creationOptions);
這一構(gòu)造函數(shù)是前 3 個構(gòu)造函數(shù)的“集大成者”,各參數(shù)的含義不再贅述。
總結(jié)一下, 每個任務(wù)一定關(guān)聯(lián)有一個任務(wù)函數(shù) 這是 Task 對象的本質(zhì)特征。
創(chuàng)建好以后,并不會自動運行,必須顯示調(diào)用它的 Start() 方法。只有此方法被調(diào)用之后,此任務(wù)才會被插入到線程(或線程池)所關(guān)聯(lián)的任務(wù)隊列中,并在任務(wù)調(diào)度器的管理下得到執(zhí)行。
Task t = new Task(() =>
{
// 任務(wù)函數(shù)代碼
});
// 任務(wù)對象創(chuàng)建完畢,但還未加入到任務(wù)隊列中
t.Start(); // 將任務(wù)追加到相應(yīng)的任務(wù)隊列中調(diào)度執(zhí)行。
創(chuàng)建任務(wù)的第 2 種方法是使用 TaskFactory 類,顧名思義,此類是一個“任務(wù)創(chuàng)建工廠”,它提供了“一堆”的公有方法可用于創(chuàng)建任務(wù)對象。
Task 類有一個靜態(tài)屬性 Factory 可用于引用一個 TaskFactory 對象。
比如,上述創(chuàng)建并啟動一個任務(wù)的代碼可以簡化為:
Task t = Task.Factory.StartNew(() =>
{
// 任務(wù)函數(shù)代碼
});
在深入了解 Task 類的基礎(chǔ)之上, TaskFactory 類的使用就沒有任何奇特之處,請讀者自行查詢 MSDN 了解 TaskFactory 類提供的另外一些方法的用法。

2 了解任務(wù)的狀態(tài)

“風(fēng)蕭蕭兮易水寒,壯士一去兮不復(fù)還”,與線程對象一樣,每一個 Task 對象都會經(jīng)歷一個生命周期,在這個生命周期的每個特定階段,對象處于一個特定的狀態(tài),并且不可能由后一個狀態(tài)“回轉(zhuǎn)”到前一個狀態(tài)。簡單地說, Task 對象的生命是一條單行線,一旦上路,就只能往前走,直到生命的終結(jié),期間絕無走回頭路的可能。
19 ? 17 所示, Task 對象擁有 8 個狀態(tài),這些狀態(tài)之間可以相互轉(zhuǎn)換。
其中, Created 是起始狀態(tài),而 Canceled Faulted RanToCompletion 3 個終止?fàn)顟B(tài),其余狀態(tài)都是中間狀態(tài)。
通過對 Task 類特定的方法的調(diào)用, Task 對象會自動進(jìn)行狀態(tài)的轉(zhuǎn)換。通常情況下軟件工程師無需考慮這一轉(zhuǎn)換過程,因為它們是由 TPL 基礎(chǔ)架構(gòu)直接管理的。
Task 類提供了一個 Status 屬性來表明當(dāng)前對象所處的狀態(tài),但出于使用方便考慮, Task 類另外還提供了 3 個相關(guān)屬性用于確定對象是否處理 3 個終止?fàn)顟B(tài)之一: IsCanceled IsFaulted IsCompleted
==========================================================
從下一講開始,將介紹在實際開發(fā)中針對各種典型開發(fā)場景使用Task實現(xiàn)并行計算的基本技術(shù)方案。

.NET4.0并行計算技術(shù)基礎(chǔ)(7)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論