对于普通优先级进程,我可以将单个线程的优先级设置为高于15吗?

时间:2012-05-17 16:03:56

标签: c++ windows multithreading timing

我在Windows 7上运行数据采集应用程序,使用C ++中的VC2010。一个线程是一个心跳,每隔0.2秒发送一次更改,以保持一些超时约为0.9秒的硬件。通常情况下,心跳呼叫需要10-20ms,并且线程会花费剩余的时间来休眠。

然而,偶尔会有1-2秒的延迟,硬件会暂时关闭。心跳线程在THREAD_PRIORITY_TIME_CRITICAL运行,对于正常的优先级进程,该线程为15。我的其他线程以正常优先级运行,虽然我使用DLL来控制其他一些硬件,并且已经注意到它在Process Explorer中启动了几个运行在15级的线程。

我无法追踪减速的来源,但我的应用程序中的其他theads在发生这种情况时会看到同样的延迟。我已经对心跳代码进行了几次优化,即使它非常简单,但偶尔也会发生故障。现在我想知道如果不为整个过程指定REALTIME_PRIORITY_CLASS,我是否可以将此线程的优先级提高到15以上。如果没有,我应该注意使用REALTIME_PRIORITY_CLASS有什么缺点吗? (除了这个心跳线程,应用程序的其余部分没有实时计时需求。)

(或者有人对如何追踪这些减速有任何想法......不确定来源是否在我的应用程序或系统中的其他位置)。

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

更新:运行磁盘碎片整理程序是一种导致大量线程延迟的好方法。即使在REALTIME_PRIORITY_CLASS上运行该进程,在THREAD_PRIORITY_TIME_CRITICAL(级别31)运行心跳线程似乎也没有帮助。接下来要尝试的是调用AvSetMmThreadCharacteristics(“专业音频”)

更新:将心跳线程调度为“专业音频”确实可以将线程的优先级提高到15以上(Base = 1,Dynamic = 24)但是当碎片整理正在运行时似乎没有任何真正的区别。我已经能够将许多减速与磁盘碎片整理程序相关联,因此关闭了每周扫描。仍然无法解释一些延迟,所以我们将增加到5-10秒的看门狗超时。

3 个答案:

答案 0 :(得分:4)

即使你可以,提高优先级也无济于事。优先级最高的可运行线程始终获取处理器。

最有可能在禁用中断时发生一些扩展中断处理。中断有效地工作在比任何线程更高的优先级。

它可能是视频,网络,磁盘,串行,USB等等。有选择地禁用或使用备用驱动程序以查看问题系统是否受到影响需要一些见解。一旦你找到了,那么找出一种防止它的方法可能从微不足道到不可能取决于它是什么。

如果不了解系统,很难说。您是否尝试在不同的 PC上运行它?

答案 1 :(得分:1)

正式地说,你不能在没有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

答案 2 :(得分:0)

我会尝试使用CreateWaitableTimer()& SetWaitableTimer()并查看它们是否受到相同的抢占问题。