2011-05-21 56 views
3

我正在學習.NET(TPL)的任務並行庫,我試圖理解它是如何工作的,我理解盜取工作的想法,但我不明白爲什麼我們使用重複隊列和How有用 ?在TPL中複製隊列

當新的任務被創建時,誰指定哪個線程應該把它放到它的任務隊列中?

你能幫助我嗎?

+0

什麼是「複製隊列」?你怎麼知道這是TPL使用的? – svick 2011-05-21 14:01:05

+0

我在這篇pdf中閱讀了這篇文章:http://www.google.com/url?sa=t&source=web&cd=2&ved=0CBsQFjAB&url=http%3A%2F%2Fciteseerx.ist.psu.edu%2Fviewdoc%2Fdownload%3Fdoi %3D10.1.1.154.5337%26rep%3Drep1%26type%3DPDF&RCT = J&q = TPL%20%2B%20duplicating%20queue%20%2B%20%20%20Design%20&EI = nvrXTYDCB9Cr8AOstdmDBQ&USG = AFQjCNGEi3k85LVoeaAfXszQcPQU6cOPSQ&SIG2 = 1jyOHVyhMHUJUp0QgucERg及CAD = RJA – 2011-05-21 17:48:45

+0

???沒有答案:( – 2011-05-21 19:18:11

回答

4

想象一下你自己實施TPL並使用普通的非複製工作隊列。因此,對於每個隊列,都有一個線程可以從隊列的尾部推出並從隊列的頭部取出多個線程(在本文中稱爲小偷)。因爲要確保每次添加到隊列中的任務都被刪除只需一次(無論是通過彈出還是通過取回),都必須在三個操作中的每一箇中使用鎖定。

從某種意義上說,當你知道只有一個線程將使用這些操作時,鎖定推送和彈出似乎是相當浪費的。但是,如果你想確保隊列的行爲正確,你就無能爲力。

你的圖書館工作,但你意識到經常發生的事情是,你正在等待一個任務,甚至還沒有開始。那麼,在當前線程中同步運行它呢?你可以做到這一點,但問題是,任務是在一個隊列中,你不能安全快速地從那裏刪除它。你可以做的是向任務添加一個標誌,指示其狀態,並以線程安全的方式訪問該標誌。

這樣,如果您最終將任務解除出隊,您將不會運行它,因爲您知道它已經運行甚至完成。隊列怎麼樣?我們說過我們想確保我們只將任務從隊列中刪除一次。但是這不再是必需的:如果我們兩次刪除某個任務,這並不重要,因爲任務本身將自行處理,並且實際上只會啓動一次。

但是這意味着我們可以從彈出和推送中刪除鎖定,從而產生一個複製隊列,這比正常的工作竊取隊列更快,因爲它具有較弱的要求:我們可以確保每個任務都從它移除至少一次。

編輯:反應的問題:

刪除的工作,將是確定的,但在排隊推動任務刪除任務!

對不起,這是一個錯誤,現在已修復。它是彈出或服用。

case 3在第6頁的fib示例中,是嗎?

是的。

爲什麼?我無法理解這個問題。

問題是,這個任務可能在任何線程的隊列中,或者它可能正在任何線程上執行。所以你必須至少搜索每個線程上運行的任務,對每個線程使用一個鎖。每當改變運行任務時,每個線程都必須使用鎖。如果任務當前未運行,則必須至少鎖定要從中移除的隊列。這也使得對隊列行爲的分析更加複雜:現在事情可能從隊列中間消失。

從彈出和推送中刪除鎖定和複製隊列之間的邏輯鏈接是什麼?

當您刪除鎖定時,無法完全確定任務僅被刪除一次。可能發生的情況是,隊列中只有一個任務,兩個不同的線程同時調用take和pop。因爲pop不使用鎖定,所以同一個任務將被移除兩次。