首页 > 解决方案 > 当 CPU 内核可用时,什么会导致 Windows 调度程序忽略高优先级线程?

问题描述

我有一个多线程应用程序,其中一个线程具有时间关键的工作。此时间关键线程在启动时设置为“时间关键”优先级。此外,应用程序中的其他线程具有处理器关联掩码集,因此这个时间关键线程始终可以完全访问八个 CPU 内核(两个 Xeon 共 12 个内核)。服务器上没有运行其他应用程序(除了 Windows 自己运行的任何服务)。

尽管如此,即使采取了所有这些预防措施,我也会记录这个时间关键线程一次没有运行 80-100 毫秒的事件。我的日志显示它有时会在任务中停止,并在 80-100 毫秒的时间间隔后再次恢复。

我的问题是:什么可能导致这些 80-100 毫秒的线程中断和/或我如何找出导致它们的原因?

其他一些可能相关的信息:

标签: c++multithreadingwindows-7windows-10scheduler

解决方案


在过去的几天里,我进行了一些测试,并且能够收集到一些有趣的数据,我将在下面进行总结。

  1. 当 CPU 大部分空闲时,这个问题几乎不会发生
  2. 我可以很容易地通过从另一个简单地使用许多线程消耗它的进程中爆破 CPU 来导致失败
  3. 我认为我可以通过进程关联掩码限制大多数线程并将时间关键线程留在它们自己的专用 CPU 上来减少问题。然而,事实证明这不是一个完整的解决方案,因为存在一些导致争​​用问题的共享锁(用于传递信息和日志工具)。短暂持有关键锁的高争用但低优先级线程将在持有锁时进入睡眠状态,让我的高优先级线程(在空闲 CPU 上,请注意)等待。
  4. 到目前为止,我运行的最有趣的测试是采用一个故障率很高的特定 Windows 7 测试系统,我在相同的硬件上安装了一个全新的 Windows 10 副本并运行完全相同的软件。在完全相同的操作条件下,这极大地降低了故障率。

最终,我认为问题归结为 Windows 没有很好地处理 1) 线程优先级,一般和 2) 优先级反转问题尤其如此。令人惊讶的是,Windows 10 似乎比 Windows 7 能更好地处理这些问题。

微软有一篇关于操作系统如何处理优先级反转的简短文章,但似乎当 CPU 被多个线程重载时,这种策略似乎不足以防止关键线程的长时间延迟,尤其是在 Windows 7 中。


推荐阅读