0

0

c# 什么是线程饥饿 c#如何避免线程池饥饿

煙雲

煙雲

发布时间:2026-01-01 09:10:03

|

773人浏览过

|

来源于php中文网

原创

线程饥饿是线程持续就绪却无法获得CPU执行权,表现为Task不调度、await卡住、线程池可用数长期为0;主因是同步等待阻塞线程池、非公平锁导致排队靠后、高优先级线程垄断时间片。

c# 什么是线程饥饿 c#如何避免线程池饥饿

线程饥饿到底是什么?不是卡死,是“饿着等不到饭”

线程饥饿不是程序崩溃或死锁,而是某个线程**一直有活干、一直想干活,但永远轮不上执行**——就像食堂窗口只给穿工装的师傅打饭,穿便装的实习生端着餐盘站一小时,饭没吃上,肚子咕咕叫。在 C# 中,典型表现是:Task 提交后长期不调度、await 卡住不动、日志停在某一步、监控显示线程池 ThreadPool.GetAvailableThreads() 接近 0 且长时间不恢复。

根本原因就三条:线程池被“占着茅坑不拉屎”的同步等待堵死;锁/信号量非公平争抢下某些线程总排末尾;高优先级线程持续霸占 CPU,低优先级线程拿不到时间片。

Task.Run + .Wait() / .Result 是线程池饥饿头号推手

这是最常见、最容易踩的坑。你写 Task.Run(() => DoWork()).Wait(),表面看只是“等一下”,实际效果是:当前线程(很可能是线程池线程)立刻被挂起阻塞,且不释放资源。如果这个调用发生在另一个 Task 内部(比如 ASP.NET Core 的中间件、或 async 方法里),等于用一个线程去等另一个线程——而那个“另一个线程”可能正排队等着上线程池……结果就是雪球越滚越大。

  • ❌ 错误示范:
    public async Task HandleRequest()
    {
        var result = Task.Run(() => HeavyCalc()).Wait(); // 饿死起点
        return Ok(result);
    }
  • ✅ 正确做法:该异步就异步,别混搭
    public async Task HandleRequest()
    {
        var result = await Task.Run(() => HeavyCalc()); // 释放线程,让别人先干活
        return Ok(result);
    }
  • 特别注意:MySql.Data 9.1.0+ 版本中,Open()ExecuteReader() 等“同步方法”底层其实是 GetAwaiter().GetResult() 封装的异步调用,本质仍是同步等待 —— 这类 SDK 要么降级,要么显式改用 OpenAsync() 等真异步 API。

线程池配置和资源隔离才是治本之策

靠默认线程池扛高并发,就像用自行车拉集装箱。当大量任务嵌套等待(父等子、子等孙),线程池很快被“逻辑阻塞”填满,新任务只能干等。这时调大 ThreadPool.SetMaxThreads() 只是延缓死亡,不能根治。

讯飞智作-讯飞配音
讯飞智作-讯飞配音

讯飞智作是一款集AI配音、虚拟人视频生成、PPT生成视频、虚拟人定制等多功能的AI音视频生产平台。已广泛应用于媒体、教育、短视频等领域。

下载
  • ✅ 为不同负载类型划分专用线程池(哪怕逻辑隔离):
    — IO 密集型(数据库、HTTP 调用):走 async/await,不占线程池;
    — CPU 密集型(图像处理、加密):用 Task.Run,但避免嵌套等待;
    — 关键后台任务(如定时统计):单独起 Thread 或用 BackgroundService,不和请求线程池共用资源。
  • ✅ 合理设置最小线程数(尤其 Windows Server):
    ThreadPool.SetMinThreads(100, 100); // 避免冷启动时创建太慢
    但最大值别乱调,OS 有开销,建议结合压测调整。
  • ✅ 用 SemaphoreSlim 控制并发上限,比“全放开再等”更可控:
    private static readonly SemaphoreSlim _dbSemaphore = new(5); // 最多5个并发DB操作
    await _dbSemaphore.WaitAsync();
    try { await db.QueryAsync(...); }
    finally { _dbSemaphore.Release(); }

锁和同步原语怎么选才不饿着人

默认 lock 是非公平的——谁抢到算谁的,老老实实排队的线程可能永远等不到。这不是 bug,是设计取舍;但业务场景需要公平性时,就得换工具

  • ✅ 用 SemaphoreSlim(支持构造函数传 true 开启公平模式):
    var sem = new SemaphoreSlim(1, 1, true); // true = 公平队列
  • ReaderWriterLockSlim 默认也是非公平,但可启用公平模式:
    var rwLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
    rwLock.EnterReadLock(); // 或 EnterWriteLock()
    不过要注意:开启公平会轻微降低吞吐,权衡而定。
  • ❌ 避免在锁内做任何可能阻塞的事(如调用 HttpClient.Send()File.ReadAllText())——这会让整个锁队列卡住,后面所有人一起饿。

真正难防的不是技术细节,而是“看起来没问题”的混合写法:比如在 async 方法里调 .Result,或者用 Task.Run 包一层同步 DB 调用再 Wait()。这些代码能跑通、单元测试也过,但一上生产,流量稍涨,线程池就悄悄饿扁了。

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

653

2023.06.20

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

244

2023.06.21

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

280

2023.07.18

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

513

2023.07.19

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

250

2023.07.25

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

384

2023.08.08

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

523

2023.08.11

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

594

2023.08.14

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 1.5万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 778人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号