更轻量级的Semaphore、AutoResetEvent、ThreadPool

内部完全使用Monitor实现,理论上比使用WaitHandler的资源消耗更少,也更快。缺点是会损失一些功能。

Semaphore源码(btw:gotdotnet上面有一个ManagedThreadPool):
 1 None.gif using  System;
 2 None.gif using  System.Threading;
 3 None.gif
 4 None.gif namespace  newsmth.Nineteen
 5 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 6InBlock.gif    public class SemaphoreLite
 7ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 8InBlock.gif        private int _count;
 9InBlock.gif        private object _sem = new object();
10InBlock.gif
11ContractedSubBlock.gifExpandedSubBlockStart.gif        ctor.#region ctor.
12InBlock.gif        public SemaphoreLite(int count)
13ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
14InBlock.gif            _count = count;
15ExpandedSubBlockEnd.gif        }

16ExpandedSubBlockEnd.gif        #endregion

17InBlock.gif
18ContractedSubBlock.gifExpandedSubBlockStart.gif        methods#region methods
19InBlock.gif        public bool Wait()
20ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
21InBlock.gif            return Wait(Timeout.Infinite);
22ExpandedSubBlockEnd.gif        }

23InBlock.gif
24InBlock.gif        public bool Wait(int millisecondsTimeout)
25ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
26InBlock.gif            if (millisecondsTimeout < 0 && millisecondsTimeout != Timeout.Infinite)
27ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
28InBlock.gif                throw new ArgumentOutOfRangeException("millisecondsTimeout 值应该大于0或等于Timeout.Infinite。");
29ExpandedSubBlockEnd.gif            }

30InBlock.gif
31InBlock.gif            lock (_sem)
32ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
33InBlock.gif                if (_count <= 0)
34ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
35InBlock.gif                    if (!Monitor.Wait(_sem, millisecondsTimeout))
36ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
37InBlock.gif                        return false;
38ExpandedSubBlockEnd.gif                    }

39ExpandedSubBlockEnd.gif                }

40InBlock.gif                _count--;
41InBlock.gif                return true;
42ExpandedSubBlockEnd.gif            }

43ExpandedSubBlockEnd.gif        }

44InBlock.gif
45InBlock.gif        public void WaitUntil(int amount)
46ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
47InBlock.gif            lock (_sem)
48ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
49InBlock.gif                while (_count < amount)
50ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
51InBlock.gif                    Monitor.Wait(_sem, Timeout.Infinite);
52ExpandedSubBlockEnd.gif                }

53InBlock.gif                _count = _count - amount;
54ExpandedSubBlockEnd.gif            }

55InBlock.gif
56ExpandedSubBlockEnd.gif        }

57InBlock.gif
58InBlock.gif        public void Pulse()
59ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
60InBlock.gif            lock (_sem)
61ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
62InBlock.gif                _count++;
63InBlock.gif                Monitor.Pulse(_sem);
64ExpandedSubBlockEnd.gif            }

65ExpandedSubBlockEnd.gif        }

66ExpandedSubBlockEnd.gif        #endregion

67ExpandedSubBlockEnd.gif    }

68ExpandedBlockEnd.gif}

69 None.gif
70 None.gif

AutoResetEvent源码:
 1 None.gif using  System;
 2 None.gif using  System.Threading;
 3 None.gif
 4 None.gif namespace  newsmth.Nineteen
 5 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 6InBlock.gif    public class AutoResetEventLite
 7ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 8InBlock.gif        private object _sem = new object();
 9InBlock.gif        private bool _isSet;
10InBlock.gif
11InBlock.gif        private static int id = 0;
12InBlock.gif        private int _currentId;
13InBlock.gif
14ContractedSubBlock.gifExpandedSubBlockStart.gif        public methods#region public methods
15InBlock.gif        public int ID
16ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
17ExpandedSubBlockStart.gifContractedSubBlock.gif            get dot.gifreturn _currentId; }
18ExpandedSubBlockEnd.gif        }

19InBlock.gif
20InBlock.gif        public AutoResetEventLite(bool initialState)
21ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
22InBlock.gif            if (initialState)
23ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
24InBlock.gif                _isSet = true;
25ExpandedSubBlockEnd.gif            }

26InBlock.gif            else
27ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
28InBlock.gif                _isSet = false;
29ExpandedSubBlockEnd.gif            }

30InBlock.gif            Interlocked.Exchange(ref _currentId, id);
31InBlock.gif            Interlocked.Increment(ref id);            
32ExpandedSubBlockEnd.gif        }

33InBlock.gif
34InBlock.gif        public bool Wait()
35ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
36InBlock.gif            return Wait(Timeout.Infinite);
37ExpandedSubBlockEnd.gif        }

38InBlock.gif
39InBlock.gif        public bool Wait(int millisecondsTimeout)
40ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
41InBlock.gif            if (millisecondsTimeout < 0 && millisecondsTimeout != Timeout.Infinite)
42ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
43InBlock.gif                throw new ArgumentOutOfRangeException("millisecondsTimeout 参数应该大于0或等于Timeout.Infinite。");
44ExpandedSubBlockEnd.gif            }

45InBlock.gif
46InBlock.gif            lock (_sem)
47ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
48InBlock.gif                bool result;
49InBlock.gif                
50InBlock.gif                if (!_isSet)
51ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
52InBlock.gif                    result = Monitor.Wait(_sem, millisecondsTimeout);
53InBlock.gif                    if (!result)
54ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
55InBlock.gif                        return false;
56ExpandedSubBlockEnd.gif                    }

57ExpandedSubBlockEnd.gif                }

58InBlock.gif                _isSet = false;
59InBlock.gif                return true;
60ExpandedSubBlockEnd.gif            }

61ExpandedSubBlockEnd.gif        }

62InBlock.gif
63InBlock.gif        public void Set()
64ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
65InBlock.gif            lock (_sem)
66ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
67InBlock.gif                if (_isSet)
68ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
69InBlock.gif                    return;
70ExpandedSubBlockEnd.gif                }

71InBlock.gif                Monitor.Pulse(_sem);
72InBlock.gif                _isSet = true;
73ExpandedSubBlockEnd.gif            }

74ExpandedSubBlockEnd.gif        }

75ExpandedSubBlockEnd.gif        #endregion

76InBlock.gif
77ExpandedSubBlockEnd.gif    }

78ExpandedBlockEnd.gif}

79 None.gif
80 None.gif

ThreadPool:
大家都知道,计算密集型应用和IO密集型应用很不同。
对计算密集型的应用,首先要保持活动线程有合适的数量,少了,多cpu机器有些cpu会闲,多了,丫又会做很多无用功在线程上下文切换上;其次,应该尽可能减少活动线程在等待某些条件时的上下文切换(如果这些条件出现非常频繁迅速的话),即用SpinWait并不断轮询,而不是Sleep或者等一个WaitHandler。
IO密集型则不同,一般情况下,这东西就跟放掉水池里的水,出水口越多,放的就越快。

说它只是个半成品,是只实现了这么一个架子,没有做什么优化,也没经过很好的测试。效率,俺猜,应该不比系统的线程池差。code project上有个功能爆强的ThreadPool,但是它是建立在WaitHandler上的。尽管“只有适合自己的才是最好的”,但是它的代码还是很推荐一读。

btw:多说两句ThreadPool中两个很关键但是很简单的数据结构,一,任务被压到ThreadPool中应该是先进先出的队列;线程的调度,应该是后进先出的stack。后者,让忙的线程更忙,闲的线程更闲,是保持活动线程数更小的重要手段,不幸的是,它常常被忽略。
  1 None.gif using  System;
  2 None.gif using  System.Collections.Generic;
  3 None.gif using  System.Text;
  4 None.gif using  System.Threading;
  5 None.gif
  6 None.gif namespace  newsmth.Nineteen
  7 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
  8InBlock.gif    //根据需求,可以改成非static的,可以增加管理功能,可以依据计算密集型应用、IO密集型应用作出不同优化等等等等
  9InBlock.gif    public static class ThreadPoolLite
 10ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 11InBlock.gif        
 12InBlock.gif        public static readonly int MaxThreadCount = Environment.ProcessorCount * 2 + 2;
 13InBlock.gif        public static readonly int InitThreadCount = Environment.ProcessorCount;
 14InBlock.gif        public static readonly int MaxQueueLength = Environment.ProcessorCount * 2 + 2;
 15InBlock.gif        private const int MaxMillisecondsTimeoutToQueueItem = 30000;
 16InBlock.gif        private const int MaxMillisecondsTimeoutToKillWorker = 180000;
 17InBlock.gif        private const int MaxMillisecondsTimeoutWaitingForWorker = 3000;
 18InBlock.gif
 19InBlock.gif        private static Stack<AutoResetEventLite> _threads = new Stack<AutoResetEventLite>();
 20InBlock.gif        private static Queue<WorkItem> _workItems = new Queue<WorkItem>();
 21InBlock.gif
 22InBlock.gif        //queue's empty count.
 23InBlock.gif        private static SemaphoreLite _queueSemR = new SemaphoreLite(MaxQueueLength);
 24InBlock.gif        //queue's count. 
 25InBlock.gif        private static SemaphoreLite _queueSemP = new SemaphoreLite(0);
 26InBlock.gif        private static SemaphoreLite _threadP = new SemaphoreLite(0);
 27InBlock.gif
 28InBlock.gif        private static int _aliveThreads = 0;
 29InBlock.gif        public static int AliveThreads
 30ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 31InBlock.gif            get
 32ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 33InBlock.gif                return _aliveThreads;
 34ExpandedSubBlockEnd.gif            }

 35ExpandedSubBlockEnd.gif        }

 36InBlock.gif
 37InBlock.gif        public static int CurrentQueueLength
 38ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 39ExpandedSubBlockStart.gifContractedSubBlock.gif            get dot.gifreturn _workItems.Count; }
 40ExpandedSubBlockEnd.gif        }

 41InBlock.gif
 42InBlock.gif        static ThreadPoolLite()
 43ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 44InBlock.gif            Thread dispatcher = new Thread(new ThreadStart(Dispatcher));
 45InBlock.gif            dispatcher.IsBackground = true;
 46InBlock.gif            dispatcher.Start();
 47InBlock.gif
 48InBlock.gif            for (int i = 0; i < InitThreadCount; i++)
 49ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 50InBlock.gif                AddNewThread();
 51ExpandedSubBlockEnd.gif            }

 52ExpandedSubBlockEnd.gif        }

 53InBlock.gif
 54InBlock.gif        public static bool QueueWorkItem(WaitCallback waitCallback)
 55ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 56InBlock.gif            return QueueWorkItem(waitCallback, null);
 57ExpandedSubBlockEnd.gif        }

 58InBlock.gif
 59InBlock.gif        public static bool QueueWorkItem(WaitCallback waitCallback, object state)
 60ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 61InBlock.gif            if (waitCallback == null)
 62ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 63InBlock.gif                throw new ArgumentNullException("waitCallback");
 64ExpandedSubBlockEnd.gif            }

 65InBlock.gif
 66InBlock.gif            WorkItem item = new WorkItem(waitCallback, state);
 67InBlock.gif
 68InBlock.gif            //wait for the queue.
 69InBlock.gif            if (_queueSemR.Wait(MaxMillisecondsTimeoutToQueueItem))
 70ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 71InBlock.gif                lock (_workItems)
 72ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
 73InBlock.gif                    _workItems.Enqueue(item);
 74ExpandedSubBlockEnd.gif                }

 75InBlock.gif                _queueSemP.Pulse();
 76InBlock.gif                return true;
 77ExpandedSubBlockEnd.gif            }

 78InBlock.gif            else
 79ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 80InBlock.gif                return false;
 81ExpandedSubBlockEnd.gif            }

 82ExpandedSubBlockEnd.gif        }

 83InBlock.gif
 84ContractedSubBlock.gifExpandedSubBlockStart.gif        private methods#region private methods
 85InBlock.gif        private static void Worker(object state)
 86ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 87InBlock.gif            AutoResetEventLite are = (AutoResetEventLite)state;
 88InBlock.gif            while (are.Wait(MaxMillisecondsTimeoutToKillWorker))
 89ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
 90InBlock.gif                WorkItem item;
 91InBlock.gif                lock (_workItems)
 92ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
 93InBlock.gif                    item = _workItems.Dequeue();
 94ExpandedSubBlockEnd.gif                }

 95InBlock.gif                _queueSemR.Pulse();
 96InBlock.gif
 97InBlock.gif                //不考虑线程上下文的改变
 98InBlock.gif                try
 99ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
100InBlock.gif                    item.WaitCallback(item.State);
101ExpandedSubBlockEnd.gif                }

102InBlock.gif                catch
103ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
104InBlock.gif                    //是不是要扔个异步事件出去再说.
105InBlock.gif                    continue;
106ExpandedSubBlockEnd.gif                }

107InBlock.gif                finally
108ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
109InBlock.gif                    lock (_threads)
110ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
111InBlock.gif                        _threads.Push(are);
112InBlock.gif                        _threadP.Pulse();
113ExpandedSubBlockEnd.gif                    }

114InBlock.gif
115InBlock.gif                    if (AliveThreads == ThreadPoolLite.MaxThreadCount)
116ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
117InBlock.gif                        Thread.Sleep(0);
118ExpandedSubBlockEnd.gif                    }

119ExpandedSubBlockEnd.gif                }

120ExpandedSubBlockEnd.gif            }

121InBlock.gif
122InBlock.gif            lock (_threads)
123ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
124InBlock.gif                if (are.Wait(0))
125ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
126InBlock.gif                    //中了五百万
127InBlock.gif                    _queueSemP.Pulse();
128ExpandedSubBlockEnd.gif                }

129InBlock.gif                Interlocked.Decrement(ref _aliveThreads);
130InBlock.gif                //压缩stack
131InBlock.gif                Stack<AutoResetEventLite> tmp = new Stack<AutoResetEventLite>();
132InBlock.gif                while (_threads.Count > 0)
133ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
134InBlock.gif                    AutoResetEventLite areT = _threads.Pop();
135InBlock.gif                    if (object.ReferenceEquals(areT, are))//感觉好多了
136ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
137InBlock.gif                        continue;
138ExpandedSubBlockEnd.gif                    }

139InBlock.gif                    tmp.Push(areT);
140ExpandedSubBlockEnd.gif                }

141InBlock.gif                _threads.Clear();
142InBlock.gif                while (tmp.Count > 0)
143ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
144InBlock.gif                    _threads.Push(tmp.Pop());
145ExpandedSubBlockEnd.gif                }

146ExpandedSubBlockEnd.gif            }

147ExpandedSubBlockEnd.gif        }

148InBlock.gif
149InBlock.gif        private static void Dispatcher()
150ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
151InBlock.gif            while (true)
152ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
153InBlock.gif                _queueSemP.Wait();
154InBlock.gif                if (_threads.Count != 0)
155ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
156InBlock.gif                    ActiveThread();
157InBlock.gif                    continue;
158ExpandedSubBlockEnd.gif                }

159InBlock.gif                else
160ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
161InBlock.gif                    if (_threadP.Wait(MaxMillisecondsTimeoutWaitingForWorker))
162ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
163InBlock.gif                        ActiveThread();
164InBlock.gif                        continue;
165ExpandedSubBlockEnd.gif                    }

166InBlock.gif                    else
167ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
168InBlock.gif                        if (AliveThreads < MaxThreadCount)
169ExpandedSubBlockStart.gifContractedSubBlock.gif                        dot.gif{
170InBlock.gif                            AddNewThread();
171InBlock.gif                            ActiveThread();
172InBlock.gif                            continue;
173ExpandedSubBlockEnd.gif                        }

174InBlock.gif                        else
175ExpandedSubBlockStart.gifContractedSubBlock.gif                        dot.gif{
176InBlock.gif                            _threadP.Wait();
177InBlock.gif                            ActiveThread();
178InBlock.gif                            continue;
179ExpandedSubBlockEnd.gif                        }

180ExpandedSubBlockEnd.gif                    }

181ExpandedSubBlockEnd.gif                }

182ExpandedSubBlockEnd.gif            }

183ExpandedSubBlockEnd.gif        }

184InBlock.gif
185InBlock.gif        private static void ActiveThread()
186ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
187InBlock.gif            _threadP.Wait();
188InBlock.gif
189InBlock.gif            AutoResetEventLite are;
190InBlock.gif            lock (_threads)
191ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
192InBlock.gif                are = _threads.Pop();
193InBlock.gif                are.Set();
194ExpandedSubBlockEnd.gif            }

195InBlock.gif            //Thread.Sleep(1);
196ExpandedSubBlockEnd.gif        }

197InBlock.gif
198InBlock.gif        private static void AddNewThread()
199ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
200InBlock.gif            AutoResetEventLite are = new AutoResetEventLite(false);
201InBlock.gif            Thread t = new Thread(new ParameterizedThreadStart(Worker));
202InBlock.gif            t.IsBackground = true;
203InBlock.gif            t.Start(are);
204InBlock.gif            Interlocked.Increment(ref _aliveThreads);
205InBlock.gif            lock (_threads)
206ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
207InBlock.gif                _threads.Push(are);
208ExpandedSubBlockEnd.gif            }

209InBlock.gif            _threadP.Pulse();
210ExpandedSubBlockEnd.gif        }

211ExpandedSubBlockEnd.gif        #endregion

212InBlock.gif
213ContractedSubBlock.gifExpandedSubBlockStart.gif        WorkItem#region WorkItem
214InBlock.gif        private class WorkItem
215ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
216InBlock.gif            public WorkItem(WaitCallback waitCallback, object state)
217ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
218InBlock.gif                _waitCallback = waitCallback;
219InBlock.gif                _state = state;
220ExpandedSubBlockEnd.gif            }

221InBlock.gif
222InBlock.gif            private WaitCallback _waitCallback;
223InBlock.gif            public WaitCallback WaitCallback
224ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
225ExpandedSubBlockStart.gifContractedSubBlock.gif                get dot.gifreturn _waitCallback; }
226ExpandedSubBlockEnd.gif            }

227InBlock.gif
228InBlock.gif            private object _state;
229InBlock.gif            public object State
230ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
231ExpandedSubBlockStart.gifContractedSubBlock.gif                get dot.gifreturn _state; }
232ExpandedSubBlockEnd.gif            }

233ExpandedSubBlockEnd.gif        }

234ExpandedSubBlockEnd.gif        #endregion

235ExpandedSubBlockEnd.gif    }

236ExpandedBlockEnd.gif}

237 None.gif
238 None.gif

欢迎拍砖。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值