更轻量级的Semaphore、AutoResetEvent、ThreadPool

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

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

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

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

欢迎拍砖。

posted on 2007-07-20 10:06  Nineteen@newsmth  阅读(3535)  评论(17编辑  收藏  举报

导航