C# 线程--第三线程池_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > C# 线程--第三线程池

C# 线程--第三线程池

 2015/3/2 12:51:23  每日一bo  程序员俱乐部  我要评论(0)
  • 摘要:概述线程池有那些优点:1.在多线程中线程池可以减少我们创建线程,并合理的复用线程池中的线程。因为在线程池中有线程的线程处于等待分配任务状态。2.不必管理和维护生存周期短暂的线程,不用在创建时为其分配资源,在其执行完任务之后释放资源。3.线程池会根据当前系统特点对池内的线程进行优化处理。线程池的缺点:我们把任务交给线程池去完成后,无法控制线程的优先级,设置线程的一些名称等信息。[不过我们可以在放入线程池之前加一层来完善这些工作]线程池参数设置示例代码:intworkerThreads
  • 标签:

概述

线程池有那些优点:

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.线程池中最大数目和最少数量我们都可以修改。

class="sentence" data-guid="b2e08eaf11af9439b0d250a2188ecf97" data-source="You cannot set the number of worker threads or the number of I/O completion threads to a number smaller than the number of processors in the computer.">[msdn建议:不能将辅助线程的数目或 I/O 完成线程的数目设置为小于计算机的处理器数目。

Services (IIS) or SQL Server, the host can limit or prevent changes to the thread pool size.">如果承载了公共语言运行时,例如由 Internet 信息服务 (IIS) 或 SQL Server 承载,主机可能会限制或禁止更改线程池大小。

更改线程池中的最大线程数时需谨慎 虽然这类更改可能对您的代码有益,但对您使用的代码库可能会有不利的影响。

将线程池大小设置得太大可能导致性能问题。 many threads are executing at the same time, the task switching overhead becomes a significant factor.">如果同时执行的线程太多,任务切换开销就成为影响性能的一个主要因素。]

线程池的使用

线程池的常用方法:

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();

输出结果:

logs_code_hide('8b59633e-3357-486d-8915-07f743e8767a',event)" src="/Upload/Images/2015030212/2B1B950FA3DF188F.gif" alt="" />
 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线程池的使用。

  • 相关文章
发表评论
用户名: 匿名