2011-12-19 47 views
2

我在網上找到了這本書。在Joseph的C#中進行線程化。我想它的榜樣線程示例C#

class ThreadTest 
{ 
    static void Main() 
    { 
     Thread t = new Thread(WriteY);   // Kick off a new thread 
     t.Start();        // running WriteY() 

     // Simultaneously, do something on the main thread. 
     for (int i = 0; i < 10000000; i++) Console.Write("x"); 
     Console.ReadLine(); 
    } 
    static void WriteY() 
    { 
     for (int i = 0; i < 10000000; i++) Console.Write("y"); 
    } 
} 

的概率是,當我運行這個程序(我給for循環中,觀察值越高)我的cpu利用率棒到100%。我不想要這個,我的意思是,無論如何減少使這個程序更少的CPU密集?我只是新的多線程概念,所以我想我應該提前問。

+18

多線程的目的是獲得更高的CPU利用率...... – 2011-12-19 12:27:02

+3

澄清:你期望* CPU看起來像這裏一樣?還有,你有多少核心? – 2011-12-19 12:28:10

+0

但是,先生,我想要有效地監視網絡中的300個節點,我認爲多線程是解決方案,但它提高了CPU的這種高利用率。我還應該使用什麼來有效監視300個節點,而不會在cpu上引發太多負載? – user1068846 2011-12-19 12:29:33

回答

1

Console.Write之後加上Thread.Sleep(num of millseconds)因爲循環將充分利用cpu。

class ThreadTest 
{ 
    static void Main() 
    { 
     Thread t = new Thread(WriteY); 
      // Kick off a new thread 
     t.Start(); 
     // running WriteY() 
     // Simultaneously, do something on the main thread. 
     for (int i = 0; i < 10000000; i++) 
     { 
       Console.Write("x"); 
       Console.ReadLine();  
     } 
    }  

    static void WriteY() 
    { 
     for (int i = 0; i < 10000000; i++) 
     { 
       Console.Write("y"); 
       Thread.Sleep(1000); // let the thread `sleep` for one seconds before running.  
     } 
    } 
} 

更新

好了,你可以使用This example,使用.NET 4的並行擴展的情況下,您有多個核心。

var result = from ipaddress in new[] 
{ 
    "111.11.11.11", 
    "22.22.22.22", 
    "22.33.44.55" 
    /* or pulled from whatever source */ 
} 
.AsParallel().WithDegreeOfParallelism(6) 
let p = new Ping().Send(IPAddress.Parse(ipaddress)) 
select new 
{ 
    site, 
    Result = p.Status, 
    Time = p.RoundtripTime 
} 

/* process the information you got*/ 
+0

你還需要一些花括號。只需添加該行不會改善事情。 - 只是說,因爲他看起來像一個初學者,並可能得到錯誤的 – yas4891 2011-12-19 12:30:52

+0

@ yas4891感謝您的抓住。 :) – OnesimusUnbound 2011-12-19 12:33:18

+1

這是什麼意思WithDegreeOfParallelism(6)? – Mou 2015-04-14 11:49:13

8

如果您可以同時使用多個資源,多線程可以改善您的應用程序。例如,如果你有多個核心,或多個CPU,我相信上面的例子應該會更好。或者,如果您有一個使用CPU的線程,並且另一個線程同時使用了該磁盤,那麼如果使用多線程,它也會表現更好。

但是,如果您有一個CPU或一個單核,上述示例將不會更好。它會表現得更糟。

+0

你的答案和都鐸王妃的答案是唯一能夠理解發生了什麼的人。這實際上是作者問題的唯一答案。 – 2011-12-19 12:37:02

5

您無法減少利用率,因爲您正在使用兩個線程(很可能在雙核上),這兩個線程都是工作密集型的(它們會循環並打印某些內容)。也許減少線程優先級可能會有所幫助,但我不認爲這就是這個例子的要點。

5

WriteY函數中的循環將盡可能快地執行。所以它會使用100%的CPU。如果您希望資源密集度較低,則可以執行以下兩項操作:

  • 更改線程的優先級。這樣一來,您的應用程序仍然會使用100%的CPU,但在你的WriteY功能的線程將「放緩」如果另一個線程需要的CPU資源

  • 添加休止符:

    static void WriteY() 
    { 
        for (int i = 0; i < 10000000; i++) 
        { 
         Console.Write("y"); 
         Thread.Sleep(100); 
        } 
    } 
    
+1

改變優先級是危險的。我自己提到過,但IMO,值得指出的是,如果你這樣做,它可能導致更大的問題。 – 2011-12-19 14:53:50

1

的多線程的整體思想是通過使用更多的計算資源(線程,這些線程在內核之間分佈)更快地完成工作,從而提高CPU利用率。

如果要降低CPU使用率,請不要使用多線程,將程序粘貼到單線程。它會運行更長時間,但消耗更少的CPU(當然,有很多優化來減少CPU佔用空間,但它們不是關於多線程的)。

如果您想要監視網絡中的300個節點,那完全是另一回事。你的例子在這裏是錯誤的,因爲你嘗試了計算密集型任務。網絡監控不是計算密集型的,它由「請求 - 等待 - 處理響應」循環組成,並行性很好:即使一個CPU可以有效處理來自一個節點的響應,同時等待另一個節點的響應。更重要的是,因爲網絡等待實際上是I/O等待,所以這個等待可以輕鬆地卸載到您的操作系統,因此它不會佔用CPU。

有上穿了良好的章節(和I/O等待)在Richter的,我強烈建議對您的問題的解決方案「通過C#,第三版CLR」。

0

更改此:

for (int i = 0; i < 10000000; i++) Console.Write("x"); 

進入這個代碼:

for (int i = 0; i < 10000000; i++) 
    { 
     Console.Write("x"); 
     Thread.Sleep(5); 
    } 
-1

使用

Thread.Sleep(x); //where x >= 0 

Thread.Yield(); 
2

首先,嘗試該程序的單線程等價物。你可能會發現它使用了你的一個內核的100%,甚至可能比它更多(假設你有多個內核,顯然超過100%/ 1是不可能的)。示例代碼是示例代碼,在所有方面通常都不現實。

很多問題都與100%的CPU使用率有關,因此一個可以導致認爲100%的CPU ==壞的東西。

事實上,100%的CPU ==昂貴的一塊電子是在幫你爲它付出做金錢的工作!

不幸的是,你爲它付出做的錢,是按照在計算機程序中的說明。如果一個計算機程序告訴它進入一個緊密的無限循環,那麼它將花費盡可能接近100%CPU(不同的調度器比其他線程做別的更好)。這是100%CPU的經典不好的情況。是的,它是按照它所告訴的,但它被告知是毫無意義的,永遠不會結束,可悲的是它是如此的「高效」,以至於它能夠很好地保持其他線程不受阻礙。

我們雖然考慮另一種情況:

  1. 的是會做是有界的工作量 - 在某些時候,它的完成。
  2. 你沒有別的東西想讓電腦做。

在這裏,越接近100%越好。低於100的每個%表示CPU正在等待發生的事情。如果我們能夠使「某些事情」更快地發生(也許速度更快的磁盤和內存),或者如果我們可以讓CPU在另一個問題上工作,那麼我們會更快地完成我們的完成點。因此,如果我們用多線程方法代替代碼,以便在另一個線程正在等待時使用CPU,並且如果這樣做的開銷不會抵消優點,那麼我們會獲得性能提升。 (另外,這意味着我們可以用一個核心的x%替換某個核心的x%,並且由於這個原因也更快)。

實際上,我們只需要幾次完成特定的工作,而不需要關心其他任何事情。事實上,即使我們這樣做了,我們也傾向於在用戶界面懸掛的同時感到困惑,忘記「讓它看起來不鎖定,永不回頭」屬於「其他任何事情」的範疇。

所以。在現實世界中,我們做什麼。

首先我們檢查是否存在真正的問題。如果它在100%CPU有一段時間,但一切(包括其他進程)都能夠完成他們的工作,那實際上很好--CPU總是在做某些事情,但這不是因爲一堆線程已經搞砸了,而是因爲所有有興趣的線程都可以做到。快樂的時光。

然後我們檢查我們實際上會遇到這種情況。如果你有一個使用x線程的多線程方法,每個線程都將花費大部分時間來等待I/O,那麼他們將不會像你的例子那樣遵循相同的模式。如果性能對於該特定任務來說很重要,那麼您可能實際上正在尋找重組它的方式,以便您可以在該問題上拋出更多線程,因此CPU有更多時間做有用的事情,而更少的時間是每個線程都在等待一些東西。

如果我們確實發現從工藝CPU使用率是傷害了一切,那麼我們可以做一些不同的事情:

  1. 只需使用一個線程。除了所有其他過程的考慮之外,這個過程是否真的很重要?很多事情我們實際上並不希望這樣做。非常非常多的事情。

  2. 降低線程優先級。儘管如此,我們認爲這是一個完成答案。這樣做有一些相當微妙的風險,最終會導致「優先級反轉」(簡單地說,高優先級的線程最終會等待低優先級的線程,這意味着只有低優先級的線程纔會運行,而您在實踐中獲得與你想要的完全相反的優先權)。

  3. 手動放棄使用YieldSleep的CPU。儘管如此,如果你正在考慮這個問題,你必須問:「這是什麼讓這種任意不同,只是隨意引入低效?」。如果你沒有一個好的答案,那麼也許單線程提供了最好的機器CPU總使用率,而不是多線程。

  4. 是否需要運行全部時間。你說上面的監控。你真的需要多快響應?如果使用多線程方法檢查所有正在監控的事件需要0.01秒,並且在發生事件發生後2秒鐘內您很樂意瞭解它,那麼您的過程比其需要的效率高出200倍,代價是其他進程。取而代之的是從計時器中取出東西。 (如果它需要一個單獨的線程0.5秒做這一切本身,還是那句話,爲什麼要多?)

上述所有的只考慮你在哪裏使用多線程做出的情況下特定任務完成得更快。值得注意的是,這只是整個多線程模式的一個子集。例如,如果你採用了上面的定時器方法,但是使用單個線程來完成這項工作,但是你在一個也在做其他事情的過程中這樣做了,那麼這仍然算作多線程;有一個線程正在執行該任務,而其他線程正在執行其他任務,並希望總體響應能力良好。

0

我讀過,有2種主要的不同類型的活動,您的處理器可以在工作。我可能在這些語句中有錯誤的措辭/語法,如果有人可以更正語法,我會很感激。

  1. 計算工作(在計算上結合的):當一個純計算任務已經給出到處理器,並且該處理器可以對其進行處理,而不需要從外部設備或組件的任何輸入。

  2. 基於輸入的工作(I/O綁定):當您的處理器正在處理某些事情時,還需要讀取或寫入磁盤,或者需要等待網絡活動。例如,從磁盤讀取文件或下載文件。

他們之間的主要區別是計算應該沒有等待使用,以便儘可能以最快的時間完成任務。 如:

for(int i = 0; i<= 10000; i++) 
{ 

} 

沒有您的系統的任何「慢」的部分沒有互動,所以對於這樣的事情,你不介意的計算/計算排水的CPU,因爲它可能會在空間完成無論如何微秒。

這對於像挖掘硬幣或蠻力組合這樣的事情尤其重要。

您不會爲這些添加「睡眠」,因爲它會不必要地拖慢你的速度。

但是,如果您的工作負載是基於輸入的,需要讀取或寫入您的硬盤驅動器或網絡;與純粹的數學工作相比,被認爲是緩慢的活動,那麼添加Thread.Sleep(x)並不是一件壞事,因爲有時您的硬盤驅動器/ Ram的速度可能不如處理器想要的那麼快。

線程是在這兩個不同的主題, 對於計算工作,在那裏你期望線程以100%的非停止運行一段時間特別有意思,那麼你最好不要超過線程數的處理器數量。

如:Environment.ProcessorCount

事實上,我幾乎建議用紗支密度是Environment.ProcessorCount -1工作(在雙核或更高的情況下)使用的所有核心的100% /處理器可導致螺紋鎖固,這實際上可能會妨礙表現。我發現在雙核心繫統上,我可以用單個核心執行更多循環/迭代,而不是完全使用兩個核心。

如果我在一個四核上,我發現我可以通過完全使用3個vs 4個來獲得更多。

(不要忘記,這些處理器中的一個具有共享的OS功能,以及使Windows窗體應用程序GUI - 如果有的話)

但是,如果您正在開發使用基於輸入的應用計算需要與很多慢速設備或依賴關係進行交互,然後超出處理器數量可能不是一件壞事。例如:如果每個線程中有很多thread.sleeps,那麼你可以策略性地規劃你的線程進入休眠狀態,而其他線程則工作。

我以前用多線程實驗室監視器完成了這項工作,該監視器旨在監視工作中實驗室機器的狀態;對於每臺實驗室機器,一個線程將運行。但它實際上每10分鐘纔會工作一次。