当前位置: 代码迷 >> C# >> CLR线程池与IO线程池
  详细解决方案

CLR线程池与IO线程池

热度:86   发布时间:2016-05-05 04:47:05.0
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 started10 00:00:03.7241812: Task 9 started11 00:00:04.2562930: Task 10 started12 00:00:04.7883300: Task 11 started13 00:00:10.0337174: Task 0 finished14 00:00:10.0337912: Task 2 finished15 00:00:10.0341861: Task 3 finished16 00:00:10.0343205: Task 13 started17 00:00:10.0342149: Task 12 started18 00:00:10.0345326: Task 1 finished19 00:00:10.0347520: Task 14 started20 00:00:10.9400517: Task 15 started21 00:00:11.0639205: Task 4 finished22 00:00:11.0643085: Task 16 started23 00:00:11.5960161: Task 5 finished24 00:00:11.5966256: Task 17 started25 00:00:12.1279212: Task 6 finished26 00:00:12.1294851: Task 18 started27 00:00:12.6609840: Task 7 finished28 00:00:12.6613285: Task 19 started29 00:00:13.1921462: Task 8 finished30 00:00:13.7240561: Task 9 finished31 00:00:14.2560682: Task 10 finished32 00:00:14.7880441: Task 11 finished33 00:00:20.0342193: Task 13 finished34 00:00:20.0354372: Task 14 finished35 00:00:20.0343117: Task 12 finished36 00:00:20.9402809: Task 15 finished37 00:00:21.0662233: Task 16 finished38 00:00:21.5983967: Task 17 finished39 00:00:22.1293673: Task 18 finished40 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线程池的使用。

  相关解决方案