更轻量级的Semaphore、AutoResetEvent、ThreadPool
内部完全使用Monitor实现,理论上比使用WaitHandler的资源消耗更少,也更快。缺点是会损失一些功能。
Semaphore源码(btw:gotdotnet上面有一个ManagedThreadPool):
AutoResetEvent源码:
ThreadPool:
大家都知道,计算密集型应用和IO密集型应用很不同。
对计算密集型的应用,首先要保持活动线程有合适的数量,少了,多cpu机器有些cpu会闲,多了,丫又会做很多无用功在线程上下文切换上;其次,应该尽可能减少活动线程在等待某些条件时的上下文切换(如果这些条件出现非常频繁迅速的话),即用SpinWait并不断轮询,而不是Sleep或者等一个WaitHandler。
IO密集型则不同,一般情况下,这东西就跟放掉水池里的水,出水口越多,放的就越快。
说它只是个半成品,是只实现了这么一个架子,没有做什么优化,也没经过很好的测试。效率,俺猜,应该不比系统的线程池差。code project上有个功能爆强的ThreadPool,但是它是建立在WaitHandler上的。尽管“只有适合自己的才是最好的”,但是它的代码还是很推荐一读。
btw:多说两句ThreadPool中两个很关键但是很简单的数据结构,一,任务被压到ThreadPool中应该是先进先出的队列;线程的调度,应该是后进先出的stack。后者,让忙的线程更忙,闲的线程更闲,是保持活动线程数更小的重要手段,不幸的是,它常常被忽略。
欢迎拍砖。
Semaphore源码(btw:gotdotnet上面有一个ManagedThreadPool):
1using System;
2using System.Threading;
3
4namespace newsmth.Nineteen
5{
6 public class SemaphoreLite
7 {
8 private int _count;
9 private object _sem = new object();
10
11 ctor.
17
18 methods
67 }
68}
69
70
2using System.Threading;
3
4namespace newsmth.Nineteen
5{
6 public class SemaphoreLite
7 {
8 private int _count;
9 private object _sem = new object();
10
11 ctor.
17
18 methods
67 }
68}
69
70
AutoResetEvent源码:
1using System;
2using System.Threading;
3
4namespace newsmth.Nineteen
5{
6 public class AutoResetEventLite
7 {
8 private object _sem = new object();
9 private bool _isSet;
10
11 private static int id = 0;
12 private int _currentId;
13
14 public methods
76
77 }
78}
79
80
2using System.Threading;
3
4namespace newsmth.Nineteen
5{
6 public class AutoResetEventLite
7 {
8 private object _sem = new object();
9 private bool _isSet;
10
11 private static int id = 0;
12 private int _currentId;
13
14 public methods
76
77 }
78}
79
80
ThreadPool:
大家都知道,计算密集型应用和IO密集型应用很不同。
对计算密集型的应用,首先要保持活动线程有合适的数量,少了,多cpu机器有些cpu会闲,多了,丫又会做很多无用功在线程上下文切换上;其次,应该尽可能减少活动线程在等待某些条件时的上下文切换(如果这些条件出现非常频繁迅速的话),即用SpinWait并不断轮询,而不是Sleep或者等一个WaitHandler。
IO密集型则不同,一般情况下,这东西就跟放掉水池里的水,出水口越多,放的就越快。
说它只是个半成品,是只实现了这么一个架子,没有做什么优化,也没经过很好的测试。效率,俺猜,应该不比系统的线程池差。code project上有个功能爆强的ThreadPool,但是它是建立在WaitHandler上的。尽管“只有适合自己的才是最好的”,但是它的代码还是很推荐一读。
btw:多说两句ThreadPool中两个很关键但是很简单的数据结构,一,任务被压到ThreadPool中应该是先进先出的队列;线程的调度,应该是后进先出的stack。后者,让忙的线程更忙,闲的线程更闲,是保持活动线程数更小的重要手段,不幸的是,它常常被忽略。
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Threading;
5
6namespace newsmth.Nineteen
7{
8 //根据需求,可以改成非static的,可以增加管理功能,可以依据计算密集型应用、IO密集型应用作出不同优化等等等等
9 public static class ThreadPoolLite
10 {
11
12 public static readonly int MaxThreadCount = Environment.ProcessorCount * 2 + 2;
13 public static readonly int InitThreadCount = Environment.ProcessorCount;
14 public static readonly int MaxQueueLength = Environment.ProcessorCount * 2 + 2;
15 private const int MaxMillisecondsTimeoutToQueueItem = 30000;
16 private const int MaxMillisecondsTimeoutToKillWorker = 180000;
17 private const int MaxMillisecondsTimeoutWaitingForWorker = 3000;
18
19 private static Stack<AutoResetEventLite> _threads = new Stack<AutoResetEventLite>();
20 private static Queue<WorkItem> _workItems = new Queue<WorkItem>();
21
22 //queue's empty count.
23 private static SemaphoreLite _queueSemR = new SemaphoreLite(MaxQueueLength);
24 //queue's count.
25 private static SemaphoreLite _queueSemP = new SemaphoreLite(0);
26 private static SemaphoreLite _threadP = new SemaphoreLite(0);
27
28 private static int _aliveThreads = 0;
29 public static int AliveThreads
30 {
31 get
32 {
33 return _aliveThreads;
34 }
35 }
36
37 public static int CurrentQueueLength
38 {
39 get { return _workItems.Count; }
40 }
41
42 static ThreadPoolLite()
43 {
44 Thread dispatcher = new Thread(new ThreadStart(Dispatcher));
45 dispatcher.IsBackground = true;
46 dispatcher.Start();
47
48 for (int i = 0; i < InitThreadCount; i++)
49 {
50 AddNewThread();
51 }
52 }
53
54 public static bool QueueWorkItem(WaitCallback waitCallback)
55 {
56 return QueueWorkItem(waitCallback, null);
57 }
58
59 public static bool QueueWorkItem(WaitCallback waitCallback, object state)
60 {
61 if (waitCallback == null)
62 {
63 throw new ArgumentNullException("waitCallback");
64 }
65
66 WorkItem item = new WorkItem(waitCallback, state);
67
68 //wait for the queue.
69 if (_queueSemR.Wait(MaxMillisecondsTimeoutToQueueItem))
70 {
71 lock (_workItems)
72 {
73 _workItems.Enqueue(item);
74 }
75 _queueSemP.Pulse();
76 return true;
77 }
78 else
79 {
80 return false;
81 }
82 }
83
84 private methods
212
213 WorkItem
235 }
236}
237
238
2using System.Collections.Generic;
3using System.Text;
4using System.Threading;
5
6namespace newsmth.Nineteen
7{
8 //根据需求,可以改成非static的,可以增加管理功能,可以依据计算密集型应用、IO密集型应用作出不同优化等等等等
9 public static class ThreadPoolLite
10 {
11
12 public static readonly int MaxThreadCount = Environment.ProcessorCount * 2 + 2;
13 public static readonly int InitThreadCount = Environment.ProcessorCount;
14 public static readonly int MaxQueueLength = Environment.ProcessorCount * 2 + 2;
15 private const int MaxMillisecondsTimeoutToQueueItem = 30000;
16 private const int MaxMillisecondsTimeoutToKillWorker = 180000;
17 private const int MaxMillisecondsTimeoutWaitingForWorker = 3000;
18
19 private static Stack<AutoResetEventLite> _threads = new Stack<AutoResetEventLite>();
20 private static Queue<WorkItem> _workItems = new Queue<WorkItem>();
21
22 //queue's empty count.
23 private static SemaphoreLite _queueSemR = new SemaphoreLite(MaxQueueLength);
24 //queue's count.
25 private static SemaphoreLite _queueSemP = new SemaphoreLite(0);
26 private static SemaphoreLite _threadP = new SemaphoreLite(0);
27
28 private static int _aliveThreads = 0;
29 public static int AliveThreads
30 {
31 get
32 {
33 return _aliveThreads;
34 }
35 }
36
37 public static int CurrentQueueLength
38 {
39 get { return _workItems.Count; }
40 }
41
42 static ThreadPoolLite()
43 {
44 Thread dispatcher = new Thread(new ThreadStart(Dispatcher));
45 dispatcher.IsBackground = true;
46 dispatcher.Start();
47
48 for (int i = 0; i < InitThreadCount; i++)
49 {
50 AddNewThread();
51 }
52 }
53
54 public static bool QueueWorkItem(WaitCallback waitCallback)
55 {
56 return QueueWorkItem(waitCallback, null);
57 }
58
59 public static bool QueueWorkItem(WaitCallback waitCallback, object state)
60 {
61 if (waitCallback == null)
62 {
63 throw new ArgumentNullException("waitCallback");
64 }
65
66 WorkItem item = new WorkItem(waitCallback, state);
67
68 //wait for the queue.
69 if (_queueSemR.Wait(MaxMillisecondsTimeoutToQueueItem))
70 {
71 lock (_workItems)
72 {
73 _workItems.Enqueue(item);
74 }
75 _queueSemP.Pulse();
76 return true;
77 }
78 else
79 {
80 return false;
81 }
82 }
83
84 private methods
212
213 WorkItem
235 }
236}
237
238
欢迎拍砖。
posted on 2007-07-20 10:06 Nineteen@newsmth 阅读(3535) 评论(17) 编辑 收藏 举报