type
status
date
slug
summary
tags
category
icon
password
Property
Aug 9, 2024 11:58 AM
线程池Thread Pool
当开始一个线程的时候,将花费几百微秒来组织类似以下的内容
- 一个新的局部变量栈(Stack)
线程池就可以节省这种开销
- 通过预先创建一个可循环使用线程的池来减少这一开销
线程池对于高效的并行编程和细粒度并发是必不可少的
他允许在不被线程启动的开销淹没的情况下运行短期操作
使用线程池线程需要注意事项
- 不可设置池线程的Name
- 池线程都是后台线程
- 阻塞池线程可使性能降级
- 你可以自由的更改池线程的优先级
- 当他释放回池的时候优先级将还原为正常状态
- 可以通过Thread.CurrentThread.IsThreadPoolThread属性来判断是否执行在池线程上
进入线程池
最简单、显式的在池线程运行代码的方式就是使用Task.Run
谁使用了线程池
- WCF、Remoting、ASP.NET、ASMX Web Services应用服务器
- System.Timers.Timer、System.Threading.Timer
- 并行编程结构
- BackgroundWorker类(现在很多余)
- 异步委托(现在很多余)
线程池中的整洁
- 线程池提供了另一个功能,即确保临时超出Compute-Bound的工作不会导致CPU超额订阅
- CPU超额订阅:活跃的线程超过了CPU的核数,操作系统就需要对线程进行时间切片
- 超额订阅对性能影响很大,时间切片需要昂贵的上下文切换,并且可能使CPU缓存失效,而CPU缓存对现代处理器的性能至关重要
CLR策略
- CLR通过对人物排队并对其启动进行节流限制来避免线程池中的超额订阅
- 它首先运行尽可能多的并发任务(只要还有CPU核),然后通过爬山算法调整并发级别,并在特定的方向上不断调整工作负载
- 如果吞吐量提高,他将继续朝同一方向(否则将反转)
- 这确保他始终追随最佳性能曲线,及时面对计算机上竞争的进程活动时也是如此
- 如果下面两点能够满足,nameCLR的策略将发挥出最佳效果
- 工作项大多是短时间运行的(<250毫秒,或者理想情况下<100毫秒),因此CLR有很多机会进行测量和调整
- 大部分时间都被阻塞的工作项不会住在线程池
如果想充分利用CPU,那么保持线程的“整洁”是非常重要的
- 作者:Kitety
- 链接:https://www.kitety.com/article/c-sharp-async-thread-pool
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章