2011-12-11 115 views
1

實例線程池:System.Threading.ThreadPool vs Semaphore?

public class Example { 
public static void Main() { 

    ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc)); //task 1 
    ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc)); //task 2 
    ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc)); //task 3 

    Console.WriteLine("Main thread does some work, then sleeps."); 

    Thread.Sleep(1000); 

    Console.WriteLine("Main thread exits."); 
} 
static void ThreadProc(Object stateInfo) { 
    Console.WriteLine("Hello from the thread pool."); 
} 
} 

例信號燈:

public class Example 
{ 
private static Semaphore _pool; 

private static int _padding; 

public static void Main() 
{ 
     _pool = new Semaphore(0, 3); 

    // Create and start five numbered threads. 
    // 
    for(int i = 1; i <= 5; i++) 
    { 
     Thread t = new Thread(new ParameterizedThreadStart(Worker)); 

     t.Start(i); 
    } 

    Thread.Sleep(500); 

    Console.WriteLine("Main thread calls Release(3)."); 
    _pool.Release(3); 

    Console.WriteLine("Main thread exits."); 
} 

private static void Worker(object num) 
{ 
    Console.WriteLine("Thread {0} begins " + 
     "and waits for the semaphore.", num); 
    _pool.WaitOne(); 

    int padding = Interlocked.Add(ref _padding, 100); 

    Console.WriteLine("Thread {0} enters the semaphore.", num); 

    Thread.Sleep(1000 + padding); 

    Console.WriteLine("Thread {0} releases the semaphore.", num); 
    Console.WriteLine("Thread {0} previous semaphore count: {1}", 
     num, _pool.Release()); 
} 
} 

我想它的一些開銷的信號燈,在這個例子中創建5個線程, 但線程池,使用內置的「線程池「(它將使用像backgroundworker這樣的現有線程)。這是正確的還是更多,是否有任何真正的優勢使用信號量,如果你只是想要一個簡單的線程池,但速度和性能是一個問題?

回答

1

僅當您期望這些線程長時間運行時才創建和管理顯式線程,或者您需要儘快執行該線程。即使那樣,你最好使用Task Parallel Library並將任務標記爲長時間運行。

線程池維護一個閒置的「活動」線程池。所以當你打電話給QueueUserWorkItem時,很可能會有一個空閒的線程可以抓住你的工作去。這並非總是如此,但往往是這樣。當您創建新線程(即var t = new Thread(...))時,總有一些啓動開銷。

此外,線程池允許您設置池線程的最大數量,並管理工作負載。因此,如果您允許四個池線程和十個工作項排隊,則線程池將確保一次只運行四個池線程。在某些方面,你可以把它看作一個隱式的信號量,因爲它不會讓這四個線程同時運行。但它可以讓你排隊儘可能多(在一些大的系統定義的限制內)。

+0

我想補充一點,如果一個線程崩潰,如果你使用的ExecutorService,這將產生一個新的線程返回線程數量(這取決於執行程序類型)。另一方面,如果您手動創建線程,則必須對其進行管理。 – Adrian

6

您正在比較蘋果和奶牛。

ThreadPool支持將線程用於小任務。它缺乏任何方便的rendez-vous機制(你的睡眠(1000)是一個弱解決這個問題)。

信號量是一種同步線程的方式,它們可以是ThreadPool線程。

+2

+1蘋果和牛。確實。 –

+0

沒有問題,只是來自msn的示例代碼,我的問題是,區別。 :) – Niklas

+0

(你可以使用WaitHandle.SignalAndWait(信號,信號2) - 用於相約機制,如果林不誤) - 用線程池 – Niklas

相關問題