线程池(Thread Pooling)
来源:互联网 发布:淘宝掌柜信用评分下降 编辑:程序博客网 时间:2024/05/16 01:35
线程池(Thread Pooling)
如果你的应用程序拥有大量的线程并花费大量的时间阻塞在一个Wait Handle上,那么你要考虑使用线程池(Thead pooling)来处理。线程池通过合并多个Wait Handle来节约等待的时间。当Wait Handle被激活时,使用线程池你需要注册一个Wait Handle到一个委托去执行。通过调用ThreadPool.RegisterWaitForSingleObject方法:
class Test
{
static ManualResetEvent starter = new ManualResetEvent(false);
public static void Main()
{
ThreadPool.RegisterWaitForSingleObject(starter, Go, "hello", -1, true);
Thread.Sleep(5000);
Console.WriteLine("Signaling worker...");
starter.Set();
Console.ReadLine();
}
public static void Go(object data, bool timedOut)
{
Console.WriteLine("Started " + data);
// Perform task...
}
}
对于Wait Handle和委托,RegisterWaitForSingleObject接受一个"黑盒"对象并传递给你的委托(就像ParameterizedThreadStart),超时设置和boolean标志指示了关闭和循环的请求。所有进入池中的线程都被认为是后台线程,这就意味着它们不再由应用程序控制,而是由系统控制直到应用程序退出。
注意:如果这时候调用Abort操作,可能会发生意想不到的情况。
你也可以通过调用QueueUserWorkItem方法使用线程池,指定委托并立即被执行。这时你不能在多任务情况下保存共享线程,但是可以得到另外的好处:线程池会保持一个线程的总容量,当作业数超出容量时自动插入任务。
class Test
{
static object workerLocker = new object();
static int runningWorkers = 100;
public static void Main()
{
for (int i = 0; i < runningWorkers; i++)
{
ThreadPool.QueueUserWorkItem(Go, i);
}
Console.WriteLine("Waiting for threads to complete...");
lock (workerLocker)
{
while (runningWorkers > 0) Monitor.Wait(workerLocker);
}
Console.WriteLine("Complete!");
Console.ReadLine();
}
public static void Go(object instance)
{
Console.WriteLine("Started: " + instance);
Thread.Sleep(1000);
Console.WriteLine("Ended: " + instance);
lock (workerLocker)
{
runningWorkers--; Monitor.Pulse(workerLocker);
}
}
}
为了传递多个对象到目标方法,你必须定义一个客户对象并包含所有属性或通过调用异步的委托。如Go方法接受两参数:
ThreadPool.QueueUserWorkItem (delegate (object notUsed) { Go (23,34); });
其他的方法可以使用异步委托。
其实对于OpenExisting函数有两个重载版本,
Mutex.OpenExisting (String)
Mutex.OpenExisting (String, MutexRights)
对于默认的第一个函数其实是实现了第二个函数 MutexRights.Synchronize|MutexRights.Modify操作。
由于监视器的设计是基于.Net框架,而Mutex类是系统内核对象封装了win32的一个内核结构来实现互斥,并且互斥操作需要请求中断来完成,因此在进行进程内线程同步的时候性能上要比互斥要好。
典型的使用Mutex同步需要完成三个步骤的操作:1.打开或者创建一个Mutex实例;2.调用WaitOne()来请求互斥对象;3.最后调用ReleaseMutex来释放互斥对象。
static public void AddString(string str)
{
// 设置超时时限并在wait前退出非默认托管上下文
if (_mtx.WaitOne(1000, true))
{
_resource.Add(str);
_mtx.ReleaseMutex();
}
}
需要注意的是,WaitOne和ReleaseMutex必须成对出现,否则会导致进程死锁的发生,这时系统(.Net2.0)框架会抛出AbandonedMutexException异常。
信号量(Semaphore)
信号量就像一个夜总会:它有确切的容量,并被保镖控制。一旦满员,就没有人能再进入,其他人必须在外面排队。那么在里面离开一个人后,队头的人就可以进入。信号量的构造函数需要提供至少两个参数-现有的人数和最大的人数。
信号量的行为有点类似于Mutex或是lock,但是信号量没有拥有者。任意线程都可以调用Release来释放信号量而不像Mutex和lock那样需要线程得到资源才能释放。
class SemaphoreTest
{
static Semaphore s = new Semaphore(3, 3); // 当前值=3; 容量=3
static void Main()
{
for (int i = 0; i < 10; i++) new Thread(Go).Start();
}
static void Go()
{
while (true)
{
s.WaitOne();
Thread.Sleep(100); // 一次只有个线程能被处理
s.Release();
}
}
}
- 线程池(Thread Pooling)
- 使用线程池 Thread Pooling
- 线程池(Thread Pooling),译自MSDN
- .NET多线程同步方法详解(七):线程池(Thread Pooling)
- Spring中的定时调度(Scheduling)和线程池(Thread Pooling)
- NET多线程同步方法详解(七):线程池(Thread Pooling)
- Spring中的定时调度(Scheduling)和线程池(Thread Pooling)
- Spring中的定时调度(Scheduling)和线程池(Thread Pooling)
- Spring中的定时调度(Scheduling)和线程池(Thread Pooling)
- Spring中的定时调度(Scheduling)和线程池(Thread Pooling)
- VC中使用系统提供的线程池(Thread Pooling)
- Chapter 23. Spring中的定时调度(Scheduling)和线程池(Thread Pooling)
- Thread Pooling(收藏)
- Thread pooling for web connections
- IOCP Thread Pooling in C#
- IOCP Thread Pooling in C#
- 线程池(Thread Pool)
- 线程池(thread pool)
- PKU1190 生日蛋糕
- 开张了!
- Flex4种方法与后台交互的方法
- extern "C"(外部链接C)
- 发烧后的咽喉肿痛自我治疗
- 线程池(Thread Pooling)
- c# 正则表达式
- 嵌入式系统开发之CISC和RISC
- (转贴)Tinkpad 笔记本
- suse 3d桌面
- NOR和NAND的区别
- Big Endian 和 Little Endian
- 金玉良言:给大学生的48条忠告(转)
- C#的数据类型