我能否将单个线程的优先级设置为高于普通优先级进程的15?

6
我有一个数据采集应用程序运行在Windows 7上,使用的是VC2010 C ++。其中一个线程是心跳线程,每0.2秒发送一次更改以保持硬件活动状态,它的超时时间大约是0.9秒。通常情况下,心跳调用需要花费10-20毫秒,而线程会在其余的时间里休眠。

然而偶尔会出现1-2秒的延迟,硬件将瞬间关闭。心跳线程以THREAD_PRIORITY_TIME_CRITICAL(优先级15)运行,这是正常优先级进程的标准。我的其他线程以普通优先级运行,尽管我使用DLL来控制其他硬件,并且发现Process Explorer启动了几个以等级15运行的线程。

我无法找到减速的来源,但当这种情况发生时,我的应用程序中的其他线程也会遇到类似的延迟。即使这个心跳代码非常简单,我已经进行了几次优化,但偶尔的失败仍在发生。现在我想知道是否可以将此线程的优先级提高到15之外,而不指定整个进程的REALTIME_PRIORITY_CLASS。如果不能,除了这个心跳线程之外,其他部分的应用程序并没有实时时间需求,我应该注意使用REALTIME_PRIORITY_CLASS的任何副作用吗?

(或者有没有人对如何追踪这些减速有任何想法...不确定源头是否可能在我的应用程序中或系统上的其他地方)。

更新:所以我实际上还没有尝试将31传递到我的AfxBeginThread调用中,结果它会忽略该值,并将线程设置为普通优先级,而不是THREAD_PRIORITY_TIME_CRITICAL的15。

更新:事实证明运行磁盘碎片整理器是导致许多线程延迟的好方法。即使以REALTIME_PRIORITY_CLASS运行进程并将心跳线程设置为THREAD_PRIORITY_TIME_CRITICAL(级别31),似乎也无济于事。下一步要尝试的是调用AvSetMmThreadCharacteristics(“Pro Audio”)。

更新:将心跳线程调度为“Pro Audio”可以增加线程的优先级超过15(基础=1,动态=24),但在运行碎片整理器时似乎没有什么实质性的区别。我已经能够将许多延迟与磁盘碎片整理器相关联,因此关闭了每周扫描。仍然无法解释一些延迟,因此我们将增加到5-10秒的看门狗超时时间。


6
当人们在关于Windows的编程问题中使用"heartbeat"和"shut down for safety reasons"这样的词汇时,我感到很害怕 :)。显然,Windows不是实时操作系统:http://en.wikipedia.org/wiki/Real-time_operating_system - HostileFork says dont trust SE
2
我认为你的看门狗太严格了。在实时操作系统上,500毫秒已经足够了,但在Windows上,低于15秒的时间是危险的。如果你可以控制你的看门狗,我建议将超时时间延长或者只有当它错过一定数量的触发器后才关闭它。 - Fozi
问题:您的硬件将在多长时间后关闭? - Fozi
2
如果您的电脑音量控制器设置为“11”,则可以将优先级设置为16。 - bmargulies
@Fozi:出于好奇,Windows上的这个15秒阈值有没有任何参考资料? - André
显示剩余3条评论
3个回答

4
即使您能够提高优先级,也不会有帮助。最高优先级的可运行线程始终获得处理器。
很可能在禁用中断时发生了某些扩展中断处理。中断实际上的工作优先级比任何线程都高。
可能是视频、网络、磁盘、串口、USB 等等。需要一些洞见才能选择性地禁用或使用备用驱动程序来查看问题系统的停顿是否受到影响。找到后,然后找出防止它的方法可能因其本身而异,从微不足道到不可能都有可能。
没有更多关于该系统的知识,很难说。您尝试在不同计算机上运行它了吗?

谢谢你的鼓励!:) 我在几台不同的电脑上运行过,但通常都安装了相同的软件和驱动程序。我会考虑哪些可以禁用并运行,但由于问题是间歇性的,每天或两天发生一次,所以很难追踪。谢谢! - jacobsee
我希望它会有所改进的原因是,这个其他硬件 DLL 有5个线程中的7个在15级。当事情变得繁忙时,我宁愿我的线程优先于它们。但是,如果像你建议的那样是硬件中断,那就没有帮助了。 - jacobsee

2

官方上你不能在没有REALTIME_PRIORITY_CLASS的进程中使用实时线程。

非官方地,你可以尝试使用未记录的NtSetInformationThread函数,详情请见: http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Thread/NtSetInformationThread.html

但由于我没有尝试过,所以对此没有更多信息。

另一方面,正如之前所说,你永远无法确定操作系统是否会在你的线程时间片到期时花费更多时间。某些编写不良的驱动程序通常是这种延迟的原因。

否则,有一款软件可以告诉你是否存在行为不当的内核部分: http://www.thesycon.de/deu/latency_check.shtml


如果你发现DPC延迟会急剧增加的情况,那么线程优先级是无法帮助你的,因为DPC(延迟过程调用)运行在比用户模式中的任何东西都更高的“优先级”(实际上是IRQL)。 - Jaka

0
我建议尝试使用CreateWaitableTimer()和SetWaitableTimer(),看看它们是否存在相同的抢占问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接