.net线程池的引入为程序员在多线程下的开发节省了大量的时间。
.net线程池由于采用其固有的内部调度算法和线程池容量算法,对于指定容量之内的线程并发和处理是很高效的。
如果遇到资源对线程池的高调用高占用,就会出现问题,线程池的容量易饱和,造成优先级低或实时性要求高的线程无法及时排队进入线程池处理。
由于线程池饱和造成的问题,在.net的异步调用中尤其明显,各种通信端口如串口、网口都是利用线程池做异步回调,虽然其有IOCP机制保证其异步调用,但是由于这些回调其放在辅助线程上,辅助线程又属于线程池内部的线程,并且辅助线程的优先级都低于主线程,会造成在通信口上的接收数据延迟,尤其是在实时系统中,这是不可忍受的。
为了避免线程池过早进入饱和,就要合理的分布线程池的使用,好钢用在刀刃上。
怎样合理处理线程池呢?
有几种策略:
1、线程池内的线程处理尽可能要处理那种占用时间很小,快速执行完的处理
2、长时间的资源处理需要放到单独的资源处理线程,而不要托管到线程池中
3、并发要尽可能均衡,对于响应要求高的请求线程池优先处理,对于响应要求不高的处理,可串行到专门的处理线程处理。
4、系统设计需要均衡负载,不能头重脚轻,什么意思呢,某一时刻,一定不能去处理所有的请求,一定要去处理最先需要处理的请求,根据优先顺序排队
5、在实时系统环境下很多场合是浪费在延迟等待上,延迟等待有很多原因,比如要将某个继电器保持多少毫秒再复位,如果利用线程池来处理,只需要在处理线程内部加上延迟时间即可,业务逻辑清晰实现简单。但是如果要延迟处理的线程过多时,就会给线程池带来称重的负担,有可能超出线程池容量。这种场合时间主要浪费在人为延时上,而不是线程的切换和资源调度上,那就把等待的过程提出来,让单独的处理线程去处理的等待,线程池负责为处理线程提供操作所需要的信号量即可。
6、调用线程池的资源尽量不要是公共资源,因为这涉及到锁操作,如果有几个互相争用资源的线程同时进入线程池,就会造成一个致命的缺陷是线程池的并发降低,线程池内部本质上是一个队列,根据线程的执行状态的排队队列,如果锁争用太厉害会造成线程池内部切换速度急剧下降,在锁的临界点上将会有大量的待锁时间浪费。