更轻量级的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):
1
using System;
2
using System.Threading;
3
4
namespace 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
using System;2
using System.Threading;3

4
namespace newsmth.Nineteen5
{6
public class SemaphoreLite7
{8
private int _count;9
private object _sem = new object();10

11
ctor.17

18
methods67
}68
}69

70

AutoResetEvent源码:
1
using System;
2
using System.Threading;
3
4
namespace 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
using System;2
using System.Threading;3

4
namespace newsmth.Nineteen5
{6
public class AutoResetEventLite7
{8
private object _sem = new object();9
private bool _isSet;10

11
private static int id = 0;12
private int _currentId;13

14
public methods76

77
}78
}79

80

ThreadPool:
大家都知道,计算密集型应用和IO密集型应用很不同。
对计算密集型的应用,首先要保持活动线程有合适的数量,少了,多cpu机器有些cpu会闲,多了,丫又会做很多无用功在线程上下文切换上;其次,应该尽可能减少活动线程在等待某些条件时的上下文切换(如果这些条件出现非常频繁迅速的话),即用SpinWait并不断轮询,而不是Sleep或者等一个WaitHandler。
IO密集型则不同,一般情况下,这东西就跟放掉水池里的水,出水口越多,放的就越快。
说它只是个半成品,是只实现了这么一个架子,没有做什么优化,也没经过很好的测试。效率,俺猜,应该不比系统的线程池差。code project上有个功能爆强的ThreadPool,但是它是建立在WaitHandler上的。尽管“只有适合自己的才是最好的”,但是它的代码还是很推荐一读。
btw:多说两句ThreadPool中两个很关键但是很简单的数据结构,一,任务被压到ThreadPool中应该是先进先出的队列;线程的调度,应该是后进先出的stack。后者,让忙的线程更忙,闲的线程更闲,是保持活动线程数更小的重要手段,不幸的是,它常常被忽略。
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Threading;
5
6
namespace 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
using System;2
using System.Collections.Generic;3
using System.Text;4
using System.Threading;5

6
namespace newsmth.Nineteen7
{8
//根据需求,可以改成非static的,可以增加管理功能,可以依据计算密集型应用、IO密集型应用作出不同优化等等等等9
public static class ThreadPoolLite10
{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 AliveThreads30
{31
get32
{33
return _aliveThreads;34
}35
}36

37
public static int CurrentQueueLength38
{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
else79
{80
return false;81
}82
}83

84
private methods212

213
WorkItem235
}236
}237

238

欢迎拍砖。
posted on 2007-07-20 10:06 Nineteen@newsmth 阅读(3547) 评论(17) 收藏 举报


浙公网安备 33010602011771号