程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C# 線程--第三線程池,

C# 線程--第三線程池,

編輯:C#入門知識

C# 線程--第三線程池,


概述

線程池有那些優點:

1.在多線程中線程池可以減少我們創建線程,並合理的復用線程池中的線程。因為在線程池中有線程的線程處於等待分配任務狀態。

2.不必管理和維護生存周期短暫的線程,不用在創建時為其分配資源,在其執行完任務之後釋放資源。

3.線程池會根據當前系統特點對池內的線程進行優化處理。

線程池的缺點:

我們把任務交給線程池去完成後,無法控制線程的優先級,設置線程的一些名稱等信息。[不過我們可以在放入線程池之前加一層來完善這些工作]

線程池參數設置

示例代碼:

int workerThreads, completionPortThreads;

ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("線程池中輔助線程的最大數目:{0}.線程池中異步 I/O 線程的最大數目:{1}", workerThreads, completionPortThreads);

ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("線程池根據需要創建的最少數量的輔助線程:{0}.線程池根據需要創建的最少數量的異步 I/O 線程:{1}", workerThreads, completionPortThreads);

//設置線程池默認參數
ThreadPool.SetMaxThreads(100, 100);
ThreadPool.SetMinThreads(2, 2);

ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("線程池中輔助線程的最大數目:{0}.線程池中異步 I/O 線程的最大數目:{1}", workerThreads, completionPortThreads);

ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("線程池根據需要創建的最少數量的輔助線程:{0}.線程池根據需要創建的最少數量的異步 I/O 線程:{1}", workerThreads, completionPortThreads);

ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("可用輔助線程的數目:{0}.可用異步 I/O 線程的數目:{1}", workerThreads, completionPortThreads);

輸出結果:

1.CLR線程池最大數:1023。I/O線程池最大數:1000。

2.線程池中最大數目和最少數量我們都可以修改。

[msdn建議:不能將輔助線程的數目或 I/O 完成線程的數目設置為小於計算機的處理器數目。

如果承載了公共語言運行時,例如由 Internet 信息服務 (IIS) 或 SQL Server 承載,主機可能會限制或禁止更改線程池大小。

更改線程池中的最大線程數時需謹慎。 雖然這類更改可能對您的代碼有益,但對您使用的代碼庫可能會有不利的影響。

將線程池大小設置得太大可能導致性能問題。 如果同時執行的線程太多,任務切換開銷就成為影響性能的一個主要因素。]

線程池的使用

線程池的常用方法:

public static bool QueueUserWorkItem(WaitCallback callBack, object state);

WaitCallback:表示線程池線程要執行的回調方法。

[ComVisible(true)]
public delegate void WaitCallback(object state);

示例代碼:

ThreadPool.SetMaxThreads(12, 12);

int workerThreads, completionPortThreads;

ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("線程池中輔助線程的最大數目:{0}.線程池中異步 I/O 線程的最大數目:{1}", workerThreads, completionPortThreads);

ThreadPool.GetMinThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("線程池根據需要創建的最少數量的輔助線程:{0}.線程池根據需要創建的最少數量的異步 I/O 線程:{1}", workerThreads, completionPortThreads);

Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();

WaitCallback callback = index =>
{
    Console.WriteLine(String.Format("{0}: Task {1} started", stopwatch.Elapsed, index));
    Thread.Sleep(10000);
    Console.WriteLine(String.Format("{0}: Task {1} finished", stopwatch.Elapsed, index));
};

for (int i = 0; i < 20; i++)
{
    ThreadPool.QueueUserWorkItem(callback, i);
}
Console.Read();

輸出結果:

1 00:00:00.0009109: Task 0 started 2 00:00:00.0011152: Task 2 started 3 00:00:00.0010331: Task 1 started 4 00:00:00.0013977: Task 3 started 5 00:00:01.0640656: Task 4 started 6 00:00:01.5959091: Task 5 started 7 00:00:02.1282115: Task 6 started 8 00:00:02.6604640: Task 7 started 9 00:00:03.1919942: Task 8 started 10 00:00:03.7241812: Task 9 started 11 00:00:04.2562930: Task 10 started 12 00:00:04.7883300: Task 11 started 13 00:00:10.0337174: Task 0 finished 14 00:00:10.0337912: Task 2 finished 15 00:00:10.0341861: Task 3 finished 16 00:00:10.0343205: Task 13 started 17 00:00:10.0342149: Task 12 started 18 00:00:10.0345326: Task 1 finished 19 00:00:10.0347520: Task 14 started 20 00:00:10.9400517: Task 15 started 21 00:00:11.0639205: Task 4 finished 22 00:00:11.0643085: Task 16 started 23 00:00:11.5960161: Task 5 finished 24 00:00:11.5966256: Task 17 started 25 00:00:12.1279212: Task 6 finished 26 00:00:12.1294851: Task 18 started 27 00:00:12.6609840: Task 7 finished 28 00:00:12.6613285: Task 19 started 29 00:00:13.1921462: Task 8 finished 30 00:00:13.7240561: Task 9 finished 31 00:00:14.2560682: Task 10 finished 32 00:00:14.7880441: Task 11 finished 33 00:00:20.0342193: Task 13 finished 34 00:00:20.0354372: Task 14 finished 35 00:00:20.0343117: Task 12 finished 36 00:00:20.9402809: Task 15 finished 37 00:00:21.0662233: Task 16 finished 38 00:00:21.5983967: Task 17 finished 39 00:00:22.1293673: Task 18 finished 40 00:00:22.6623133: Task 19 finished View Code

1:00秒共開啟4個線程(為線程池中最少線程數:當達到線程池中創建線程最小線程時,線程池開始創建線程)。
2:01到04秒之間平均1秒創建一個線程.線程池創建線程每秒不會超過2個。
3:04秒時線程池中的線程數已達最大值,無法在創建新的線程。
4:10秒時線程池中線程ID0-4已完成任務,線程池又開始重新創建線程(線程ID為:12-15)共4個。

CLR線程池與IO線程池

測試CLR線程池占滿後,會不會影響IO線程池的正常使用?

示例代碼:

ThreadPool.SetMaxThreads(5, 5);    
ThreadPool.SetMinThreads(5, 5);

int workerThreads, completionPortThreads;

ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("線程池中輔助線程的最大數目:{0}.線程池中異步 I/O 線程的最大數目:{1}", workerThreads, completionPortThreads);

ManualResetEvent waitHandle = new ManualResetEvent(false);

Stopwatch watch = new Stopwatch();
watch.Start();

//IO線程池
WebRequest request = HttpWebRequest.Create("http://www.taobao.com/");
request.BeginGetResponse(ar =>
{
    var response = request.EndGetResponse(ar);
    Console.WriteLine(watch.Elapsed + ": Response Get");
}, null);


//CLR線程池
for (int i = 0; i < 10; i++)
{
    ThreadPool.QueueUserWorkItem(index => 
    {
        Console.WriteLine(String.Format("{0}: Task {1} started", watch.Elapsed, index));
        waitHandle.WaitOne(); //阻塞線程池
    },i);
}

Console.Read();

輸出結果:

1. 把CLR線程池最大線程數和IO線程池最大線程數都設置為:5.

2.向CLR線程池中增加10個線程任務,並且阻塞線程池。最後輸出結果中只打印出5個線程運行的信息。CLR線程池已達最大線程數,IO線程依然有回復數據。

證明CLR線程池占滿後不會影響到IO線程池的使用。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved