标签:ons 问题 sdn 线程池 www. www 值传递 rtt reading
在多线程的程序中,经常会出现两种情况:
一种情况: 应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应
这一般使用ThreadPool(线程池)来解决;
另一种情况:线程平时都处于休眠状态,只是周期性地被唤醒
这一般使用Timer(定时器)来解决;
本篇文章单单讲线程池[ThreadPool]
ThreadPool类 MSDN帮助信息: http://msdn.microsoft.com/zh-cn/library/system.threading.threadpool.aspx#Y0
将任务添加进线程池:
ThreadPool.QueueUserWorkItem(new WaitCallback(方法名));
重载
ThreadPool.QueueUserWorkItem(new WaitCallback(方法名), 参数);
因为ThreadPool是静态类 所以不需要实例化.
对于线程池主要的控制有控制线程数大小:
public static bool SetMaxThreads( int workerThreads, int completionPortThreads )
参数:
例子:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;namespace 多线程池试验{ class Program { public static void Main() { ThreadPool.SetMaxThreads(3, 3); for (int i = 0; i < 50; i++) { thr t = new thr(); ThreadPool.QueueUserWorkItem(new WaitCallback(t.ThreadProc), i); } Console.WriteLine("断点测试"); Thread.Sleep(100000); Console.WriteLine("运行结束"); } public class thr { public void ThreadProc(object i) { Console.WriteLine("Thread[" + i.ToString() + "]"); Thread.Sleep(1000); } } }} |
输出结果:
您会发现 断点测试 在上面了, 这是什么原因呢?
原因:
1. 线程池的启动和终止不是我们程序所能控制的, 我反正是不知道的, 你如果知道的话 可以发邮件给我 henw@163.com
2. 线程池中的线程执行完之后是没有返回值的.
总之一句话, 我们不知道线程池他干了什么, 那么我们该怎么解决 任务完成问题呢?
操作系统提供了一种”信号灯”(ManualResetEvent)
ManualResetEvent 允许线程通过发信号互相通信。通常,此通信涉及一个线程在其他线程进行之前必须完成的任务。当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用 Reset 以将 ManualResetEvent 置于非终止状态,此线程可被视为控制 ManualResetEvent。调用 ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号。当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。一旦它被终止,ManualResetEvent 将保持终止状态(即对 WaitOne 的调用的线程将立即返回,并不阻塞),直到它被手动重置。可以通过将布尔值传递给构造函数来控制 ManualResetEvent 的初始状态,如果初始状态处于终止状态,为 true;否则为 false。
详细见MSDN: http://msdn.microsoft.com/zh-cn/library/system.threading.manualresetevent.aspx
主要使用了
eventX.WaitOne(Timeout.Infinite, true); 阻止当前线程,直到当前 WaitHandle 收到信号为止。
eventX.Set(); 将事件状态设置为终止状态,允许一个或多个等待线程继续。
修改后的程序:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading;namespace多线程池试验{classProgram{publicstaticvoidMain(){//新建ManualResetEvent对象并且初始化为无信号状态ManualResetEvent eventX =newManualResetEvent(false);ThreadPool.SetMaxThreads(3, 3);thr t =newthr(15, eventX);for(inti = 0; i < 15; i++){ThreadPool.QueueUserWorkItem(newWaitCallback(t.ThreadProc), i);}//等待事件的完成,即线程调用ManualResetEvent.Set()方法//eventX.WaitOne 阻止当前线程,直到当前 WaitHandle 收到信号为止。eventX.WaitOne(Timeout.Infinite,true);Console.WriteLine("断点测试");Thread.Sleep(10000);Console.WriteLine("运行结束");}publicclassthr{publicthr(intcount,ManualResetEvent mre){iMaxCount = count;eventX = mre;}publicstaticintiCount = 0;publicstaticintiMaxCount = 0;publicManualResetEvent eventX;publicvoidThreadProc(objecti){Console.WriteLine("Thread["+ i.ToString() +"]");Thread.Sleep(2000);//Interlocked.Increment()操作是一个原子操作,作用是:iCount++ 具体请看下面说明//原子操作,就是不能被更高等级中断抢夺优先的操作。你既然提这个问题,我就说深一点。//由于操作系统大部分时间处于开中断状态,//所以,一个程序在执行的时候可能被优先级更高的线程中断。//而有些操作是不能被中断的,不然会出现无法还原的后果,这时候,这些操作就需要原子操作。//就是不能被中断的操作。Interlocked.Increment(refiCount);if(iCount == iMaxCount){Console.WriteLine("发出结束信号!");//将事件状态设置为终止状态,允许一个或多个等待线程继续。eventX.Set();}}}}}输出结果:
顺序正常了.
程序源码: 多线程池试验.zip
http://www.cnblogs.com/henw/archive/2012/01/06/2314870.html
标签:ons 问题 sdn 线程池 www. www 值传递 rtt reading
原文地址:http://www.cnblogs.com/zxtceq/p/7779396.html