为什么c#线程在执行期间会空闲
本文关键字:执行期 线程 为什么 | 更新日期: 2023-09-27 18:12:34
我有一个调度程序作为后台线程运行的应用程序的ASP启动。网的网站。用户可以启动各种任务(警报电子邮件/文件生成等),这是插入到一个数据库表。调度器将从数据库中挑选任务,并将项目推入堆栈。此外,调度程序有一个线程池,运行10个后台线程,这些线程将从堆栈中弹出任务项并执行它。
这在一个web服务器上运行良好,但在其他web服务器上表现奇怪。线程空闲6-12秒,没有任何原因,即使堆栈中有项目也不做任何事情。
- 在栈对象上使用lock()使Push &弹出线程安全提示
- try Thread.Yield()给cpu yield来执行其他线程,但是执行速度变慢并且仍然处于空闲状态
- 尝试Thread.Sleep(0)给cpu yield以执行其他线程,但执行速度变慢并且仍然处于空闲状态
- 记录所有方法的入口和退出,以检查是否在执行过程中出现错误,但没有运气
我的问题:
- 线程在。net中的执行是不确定的吗?
- 是否需要指定Thread.Yield()或Thread.Sleep(0)来给cpu喘息时间?
- 为什么在相同配置的盒子上表现不同?是否有任何机器/环境特定因素影响线程的执行?
2013年5月8日更新
有两个盒子在农场,都是相同的硬件配置,安装相同的软件配置以及Windows 2008 64bit/IIS7。两个网站服务器只有一个网站,每个网站都有相同的构建。两个站点的应用程序池以集成模式运行在Framework V4.0上。这是一个遗留代码,自过去两年以来没有机会。
我们尝试了几次迭代,在所有情况下,webserver1执行没有任何问题,并迅速完成后台工作。
但是webserver2有明显的延迟,性能很差。我们尝试了广泛的日志记录,捕获所有方法的条目/退出。场景是这样的,所有线程在2秒内正常工作,然后空闲6-12秒,再次变为活动并执行接下来的2秒,然后再次空闲。这种行为一直持续到任务完成。应用程序池/iis日志中没有异常,没有应用程序终止,没有错误。
您的线程正在反复尝试获取可能导致争用的锁。但不应该是6-12秒-答案只有调试器可以提供。
您可以使用AutoResetEvent
并在工作线程中等待它-并且Set
在将item推入堆栈时发生事件。
好了,我们终于解决了这个问题。
web服务器的一个cpu内核达到100%并且再也没有回来。而其他核心在0-5%。
我们对正常-中等-重负载进行了负载测试。在生成正常到中等负载的同时,服务器正在正常地提供服务,并与所有其他cpu内核适当地共享进程执行。但是,当我们产生沉重的负载时,情况发生了变化,服务器努力在内核之间分配负载,线程空闲6-7秒。我们假设由于一个cpu核心的故障,它处理一些模糊逻辑来分配进程在核心之间。
经过进一步调查,我们发现是Windows NT内核导致了这个问题,可能是由于损坏或驱动程序相关的问题。