C# 線程池

來源:互聯網
上載者:User

許多應用程式使用多個線程,但這些線程經常在休眠狀態中耗費大量的時間來等待事件發生。其他線程可能進入休眠狀態,並且僅定期被喚醒以輪詢更改或更新狀態資訊,然後再次進入休眠狀態。為了簡化對這些線程的管理,.NET架構為每一個進程提供了一個線程池,使應用程式能夠根據需要來有效地利用多個線程。一個線程監視排到線程池的若干個等待操作的狀態。當一個等待操作完成時,線程池中的一個輔助線程就會執行對應的回呼函數。線程池中的線程由系統進行管理,程式員不需要費力於線程管理,可以集中精力處理應用程式任務。

線程池是一種多執行緒形式,處理過程中將任務添加到隊列,然後在建立線程後自動啟動這些任務。線程池線程都是後台線程。每個線程都使用預設堆棧大小,以預設的優先順序運行,並處於多執行緒 Apartment中。如果某個線程在Managed 程式碼中空閑(如正在等待某個事件),則線程池將插入另一個輔助線程來使所有處理器保持繁忙。如果所有線程池線程都始終保持繁忙,但隊列中包含掛起的工作,則線程池將在一段時間之後建立另一個輔助線程。但線程的數目永遠不會超過最大值。超過最大值的其他線程可以排隊,但它們要等到其他線程完成後才啟動。

線程池特別適合於執行一些需要多個線程的任務。使用線程池能夠最佳化這些任務的執行過程,從而提高輸送量,它不僅能夠使系統針對此進程最佳化該執行過程,而且還能夠使系統針對電腦上的其他進程最佳化該執行過程。如果需要啟動多個不同的任務,而不想分別設定每個線程的屬性,則可以使用線程池。

如果應用程式需要對線程進行特定的控制,則不適合使用線程池,需要建立並管理自己的線程。不適合使用線程池的情形包括:

— 如果需要使一個任務具有特定的優先順序。

— 如果具有可能會長時間運行(並因此阻塞其他任務)的任務。

— 如果需要將線程放置到單一執行緒 Apartment中(線程池中的線程均處於多執行緒 Apartment中)。

— 如果需要用永久標識來標識和控制線程,比如想使用專用線程來中止該線程,將其掛起或按名稱發現它。

System.Threading.ThreadPool類實現了線程池。ThreadPool類是一個靜態類,它提供了管理線程池的一系列方法。

ThreadPool.QueueUserWorkItem方法線上程池中建立一個線程池線程來執行指定的方法(用委託WaitCallback來表示),並將該線程排入線程池的隊列等待執行。QueueUserWorkItem方法的原型為:

public static Boolean QueueUserWorkItem(WaitCallback wc, Object state);

public static Boolean QueueUserWorkItem(WaitCallback wc);

這些方法將“工作項目”(和可選狀態資料)排列到線程池的線程中,並立即返回。工作項目只是一種方法(由wc參數標識),它被調用並傳遞給單個參數,即狀態(狀態資料)。沒有狀態參數的QueueUserWorkItem版本將null傳遞給回調方法。線程池中的某些線程將調用System.Threading.WaitCallback委託表示的回調方法來處理該工作項目。回調方法必須與System.Threading.WaitCallback委託類型相匹配。WaitCallback定義如下:

public delegate void WaitCallback(Object state);

調用QueueUserWorkItem時傳入的Object型別參數將傳遞到任務過程,可以通過這種方式來向任務過程傳遞參數。如果任務過程需要多個參數,可以定義包含這些資料的類,並將類的執行個體強制轉換為Object資料類型。

每個進程都有且只有一個線程池。當進程啟動時,線程池並不會自動建立。當第一次將回調方法排入隊列(比如調用ThreadPool.QueueUserWorkItem方法)時才會建立線程池。一個線程監視所有已排隊到線程池中的任務。當某項任務完成後,線程池中的線程將執行相應的回調方法。在對一個工作項目進行排隊之後將無法取消它。

線程池中的線程數目僅受可用記憶體的限制。但是,線程池將對允許在進程中同時處於活動狀態的線程數目強制實施限制(這取決於CPU的數目和其他因素)。預設情況下,每個系統處理器最多可以運行25個線程池線程。通過使用ThreadPool.GetMaxThreads和ThreadPool.SetMax Threads方法,可以擷取和設定線程池的最大線程數。

即使是在所有線程都處於空閑狀態時,線程池也會維持最小的可用線程數,以便隊列任務可以立即啟動。將終止超過此最小數目的空閑線程,以節省系統資源。預設情況下,每個處理器維持一個空閑線程。使用ThreadPool.GetMinThreads和ThreadPool.SetMinThreads方法可以擷取和設定線程池所維持的空閑線程數。

下面的程式用於計算如下的函數的值:

 

// ThreadPool.cs

// 線程池樣本

using System;

using System.Threading;

public class Test

{

    // 存放要計算的數值的欄位

    static double number1 = -1;

    static double number2 = -1;

    public static void Main()

    {

        // 擷取線程池的最大線程數和維護的最小空閑線程數

        int maxThreadNum, portThreadNum;

        int minThreadNum;

        ThreadPool.GetMaxThreads(out maxThreadNum, out portThreadNum);

        ThreadPool.GetMinThreads(out minThreadNum, out portThreadNum);

        Console.WriteLine("最大線程數:{0}", maxThreadNum);

        Console.WriteLine("最小空閑線程數:{0}", minThreadNum);

        // 函數變數值

        int x = 15600;

        // 啟動第一個任務:計算x的8次方

        Console.WriteLine("啟動第一個任務:計算{0}的8次方。", x);

        ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc1), x);

        // 啟動第二個任務:計算x的8次方根

        Console.WriteLine("啟動第二個任務:計算{0}的8次方根。", x);

        ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc2), x);

        // 等待,直到兩個數值都完成計算

        while (number1 == -1 || number2 == -1) ;

        // 列印計算結果

        Console.WriteLine("y({0}) = {1}", x, number1 + number2);

    }

    // 啟動第一個任務:計算x的8次方

    static void TaskProc1(object o)

    {

        number1 = Math.Pow(Convert.ToDouble(o), 8);

    }

    // 啟動第二個任務:計算x的8次方根

    static void TaskProc2(object o)

    {

        number2 = Math.Pow(Convert.ToDouble(o), 1.0 / 8.0);

    }

}

該程式的輸出結果為:

最大線程數:25

最小空閑線程數:1

啟動第一個任務:計算15600的8次方。

啟動第二個任務:計算15600的8次方根。

y(15600) = 3.50749278894883E+33

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.