5

我有一个在 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 秒的看门狗超时。

4

3 回答 3

4

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

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

它可能是视频、网络、磁盘、串行、USB 等。需要一些洞察力来选择性地禁用或使用备用驱动程序来查看问题系统犹豫是否受到影响。一旦你发现了这一点,然后找出一种方法来防止它可能会从微不足道到不可能,这取决于它是什么。

没有更多关于系统的知识,很难说。您是否尝试过在另一台 PC 上运行它?

于 2012-05-17T16:11:14.403 回答
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

于 2012-07-31T15:24:27.200 回答
0

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

于 2012-05-30T16:18:32.737 回答