我可以为普通优先级进程设置单个线程的优先级高于 15 吗?
Posted
技术标签:
【中文标题】我可以为普通优先级进程设置单个线程的优先级高于 15 吗?【英文标题】:Can I set a single thread's priority above 15 for a normal priority process? 【发布时间】:2012-05-17 16:03:55 【问题描述】:我有一个在 Windows 7 上运行的数据采集应用程序,使用 C++ 中的 VC2010。一个线程是一个心跳,它每 0.2 秒发送一次更改以保持某些硬件的活动,该硬件的超时时间约为 0.9 秒。通常,心跳调用需要 10-20 毫秒,而线程其余时间都在休眠。
但有时会有 1-2 秒的延迟,并且硬件会立即关闭。心跳线程在 THREAD_PRIORITY_TIME_CRITICAL 运行,对于正常的优先级进程,它是 15。我的其他线程以正常优先级运行,尽管我使用 DLL 来控制其他一些硬件,并且注意到使用 Process Explorer 它启动了几个在 15 级运行的线程。
我无法找到减速的原因,但我的应用程序中的其他问题在发生这种情况时会看到相同类型的延迟。我对心跳代码做了一些优化,虽然很简单,但偶尔还是会出现故障。现在我想知道是否可以在不为整个进程指定 REALTIME_PRIORITY_CLASS 的情况下将此线程的优先级提高到 15 以上。如果没有,我应该注意使用 REALTIME_PRIORITY_CLASS 有什么缺点吗? (除了这个心跳线程,应用程序的其余部分没有实时计时需求。)
(或者是否有人对如何追踪这些减速有任何想法...不确定来源是否可能在我的应用程序中或系统上的其他位置)。
更新:所以我实际上并没有尝试将 31 传递给我的 AfxBeginThread 调用,结果它忽略了该值并将线程设置为正常优先级,而不是我通过 THREAD_PRIORITY_TIME_CRITICAL 获得的 15。
更新:事实证明,运行磁盘碎片整理程序是导致大量线程延迟的好方法。即使在 REALTIME_PRIORITY_CLASS 上运行进程并且在 THREAD_PRIORITY_TIME_CRITICAL(级别 31)上运行心跳线程似乎也无济于事。接下来要尝试的是调用 AvSetMmThreadCharacteristics("Pro Audio")
更新:将心跳线程调度为“Pro Audio”确实可以将线程的优先级提高到 15 以上(Base=1,Dynamic=24),但在运行碎片整理时似乎没有任何真正的区别。我已经能够将许多减速与磁盘碎片整理程序相关联,因此关闭了每周扫描。仍然无法解释一些延迟,因此我们将增加到 5-10 秒的看门狗超时。
【问题讨论】:
当人们在有关 Windows 的编程问题中使用“心跳”和“出于安全原因关闭”之类的词时,我感到害怕。 :) 它肯定不是 RTOS:en.wikipedia.org/wiki/Real-time_operating_system 我认为你的看门狗太严格了。在 RTOS 上 500 毫秒就足够了,但在 Windows 上,任何低于 15 秒的时间都是有风险的。如果您可以控制看门狗,那么我建议您延长超时时间,或者仅在它错过一定数量的触发器时才将其关闭。 问题:您的硬件将在多长时间后关闭? 如果在最后一个心跳之后 0.5 秒没有收到心跳,将关闭。我喜欢你关于增加超时的评论,我们可能会这样做,但我想先尝试从软件方面进行优化。我认为我们不能达到 15 秒,但可能是 5 秒 如果您的电脑音量控制设置为“11”,您可以将优先级设置为 16。 【参考方案1】:即使可以,提高优先级也无济于事。最高优先级的可运行线程始终获取处理器。
很可能在中断被禁用时发生了一些扩展的中断处理。中断有效地以比任何线程更高的优先级工作。
可能是视频、网络、磁盘、串行、USB 等。需要一些洞察力来选择性地禁用或使用备用驱动程序来查看问题系统犹豫是否受到影响。一旦你发现了这一点,然后找出一种方法来防止它可能是微不足道的,也可能是不可能的,具体取决于它是什么。
没有更多关于系统的知识,很难说。您是否尝试在不同的 PC 上运行它?
【讨论】:
感谢您的信任投票 :) 我在几台不同的计算机上运行过,但通常总是安装相同的软件和驱动程序。我会考虑我可以禁用和运行什么,但由于问题是间歇性的,似乎每天或两天都会发生,因此很难追踪。谢谢! 我希望它会有所作为的原因是,这个其他硬件 dll 在 15 级有 7 个线程中的 5 个。当事情变得繁忙时,我宁愿我的线程优先他们。但是,如果它是您建议的硬件中断,那将无济于事。【参考方案2】:官方不能在没有 REALTIME_PRIORITY_CLASS 的进程中使用 REALTIME 线程。
非正式地你可以玩无证的NtSetInformationThread
看:
http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Thread/NtSetInformationThread.html
但由于我没有尝试过,所以我没有更多关于此的信息。
另一方面,正如之前所说,您永远无法确定操作系统不会在您的线程的时间片到期时花费时间。某些写得不好的驱动程序通常是导致这种延迟的原因。
否则有一个软件可以告诉你是否有异常的内核部分: http://www.thesycon.de/deu/latency_check.shtml
【讨论】:
如果您发现 DPC 延迟会急剧增加的情况,那么线程优先级无法帮助您,因为 DPC(延迟过程调用)以比用户模式下的任何东西更高的“优先级”(实际上是 IRQL)运行。 ..【参考方案3】:我会尝试使用 CreateWaitableTimer() 和 SetWaitableTimer() 看看它们是否会遇到相同的抢占问题。
【讨论】:
以上是关于我可以为普通优先级进程设置单个线程的优先级高于 15 吗?的主要内容,如果未能解决你的问题,请参考以下文章