1. 基本思路
写了个简易的线程池,基本的思路是:
- 有1个调度线程,负责维护WorkItem队列、管理线程(是否要增加工作线程)、调度(把工作项赋给工作线程)等
- 线程数量随WorkItem的量动态调整,超时后自动退出
- 可以从WorkItem里拿到结果,并执行取消等动作
2. 设计点
需要考量的地方如下:
- 是否要设置1个单独的调度线程?如果不设置,那么只能在工作项Enqueue的时候,根据繁忙程度决定是否生成新的线程。如果短时间内涌入大量工作项,并且都是短工作项(执行时间<1s),则会一下子生成一大堆idle线程。SmartThreadPool里就是这么设计的。
- 我的选择是,增加1个单独的调度线程。默认每1秒调度1次,避免工作项一直等待,也避免工作项太多时线程增长太快。
- 工作线程放在1个堆栈里,保证后进先出,即越是使用频繁的线程,越是经常用它。越是休息的久的线程,越是不让它干活。这样空闲的线程会尽快退出,减少了资源的占用和CPU的调度。
- MinThread在线程池初始化时生成,永不退出。是否应该在第1个工作项Enqueue的时候,再生成MinThread呢?目前是固定某个线程为MinThread,是否应该不固定,只保证Minimun的线程数量?
- 工作项队列是否需要有长度限制?我设定为默认1k,有丢弃策略,默认是不丢弃,这时会忽略长度限制。
- 目前线程的名字是当前正在执行的工作项的名字,这是为了调试方便。理想的情况是,随时可以打印1个snapshot,展现线程池里的所有状态,哪些线程空闲、另一些在执行哪些工作项等。
3. 与SmartThreadPool的比较
当然,目前功能上还非常简单,可以作为线程池入门级的学习参考。比如以下功能都没有实现:
- 不能控件Thread和WorkItem的Priority
- 不能设置Thread的Background、ApartmentState、StackSize(当然这个很容易添加)
- 没有PerformanceCounter(这个就不太容易了)
- 没有对WorkItem和State的释放(Dispose)
- 没有延迟执行PostExecute、也没有StartSuspended等
- 没有暴露足够的属性和事件,不易于外部了解线程池内的运行状态和注册事件处理方法