【问题标题】:QProcess ProcessState sufficient for Blocked Processes?QProcess ProcessState 对于阻塞进程是否足够?
【发布时间】:2014-02-04 08:43:40
【问题描述】:

我想知道一个进程(以 QProcess 类开始)是否不再响应。例如,我的进程是一个每秒只打印 1 个的应用程序。

我的问题是我想知道(出于某种神秘原因)该进程是否被阻塞了一小段时间(超过 1 秒,这是人类可以注意到的)。

但是,QProcess 的不同状态(未运行、启动、运行)不包括“阻塞”状态。

当我们在任务管理器中收到“无响应”消息时,我的意思是被阻止为“不响应操作系统”。例如当 Windows MMI(如 explorer.exe)被阻止并变成白色时。

但是:我想检测任何进程的“无响应”状态。不仅仅是 MMI。

有没有办法检测到这种状态?

【问题讨论】:

  • 进程是否应该将数据写入标准输出\error?
  • 可能是“阻塞” - 是平台相关状态。而且它在大多数 Qt 的顶级平台上都不存在。您能否更准确地解释一下“被阻止”是什么意思?

标签: c++ qt process


【解决方案1】:

Qt 没有为此提供任何 API。您需要使用特定于平台的机制。在某些平台(Windows!)上,没有挂起应用程序的概念,只有挂起窗口的概念。您可以拥有一个同时具有响应和无响应窗口的应用程序:)

在 Windows 上,您将使用 EnumWindows 枚举所有窗口,通过比较从 GetWindowThreadProcessIdprocess->pid() 的 pid 检查它们是否属于您的进程,最后通过 IsHungAppWindow 检查窗口是否挂起。

注意事项

一般来说,没有“无响应”过程的包罗万象的概念。

假设您有一个网络服务器。它没有响应是什么意思?它的负载很重,因此它可能会拒绝某些传入连接。从您的角度来看,这是“不回应”吗?可能是这样,但是您对此无能为力 - 杀死并重新启动该进程不会解决它。如果有的话,这将使已经连接的客户端变得更糟。

假设您有一个进程在读取文件系统时被阻塞,因为它尝试访问的特定驱动器速度很慢或负载过重。这是否意味着它没有响应?杀死并重新启动它总能解决这个问题吗?如果该进程随后从文件开头重试读取,则可能会使事情变得更糟。

假设您的 GUI 流程设计不佳。它正在阻止 GUI 线程中的串行端口读取。它正在执行的读取需要很长时间,并且 GUI 在几秒钟内没有响应。你杀死了这个进程,它重新启动并再次尝试那个长读 - 你只会让事情变得更糟。

您必须在此处非常小心

解决方案思路

有多种方法可以确定什么是“响应式”流程。前面已经提到,带有 GUI 的进程由 Windows 和 OS X 上的操作系统监控。因此,可以使用原生 API 来查询窗口或进程是否挂起。这对于提供 UI 的应用程序是有意义的,并且需要注意上述警告。

如果流程正在提供服务,您可以定期使用该服务来确定它是否仍然可用,但须遵守某些截止日期。任何关于如何处理“挂起”进程的选择都应考虑系统的 CPU 和 I/O 负载。

保留服务对服务请求的响应延迟的历史记录可能是值得的。只有延迟的“大”变化才应被视为问题的指示。假设您正在跟踪平均延迟。可以将最终期限设置为之前平均延迟的 50 倍。错过这个截止日期,该服务将被假定为已死并且可以强制回收。 “动作标志”期限可以设置为平均延迟的 5-10 倍。然后将给一个人一个选项来有序地重新启动服务。当延迟回落到比触发标志的截止日期低 30% 时,该标志将被自动删除。

如果你是被监控进程的开发者,那么你可以反转监控方面,成为被监控进程的被动看门狗。然后,受监视的进程必须定期、主动地“唤醒”看门狗,以表明它还活着。唤醒信号的发射(通用术语)应在代码中的战略位置执行。定期接收唤醒“信号”应该可以让您推断该过程仍然存在。您可能有多个唤醒信号,标记有被监视进程中的位置。一切都取决于进程有多少线程,它在做什么等等。

【讨论】:

  • @Xaltar 如果我们谈论的是 Windows,那么被挂起的概念不适用,因为要接收消息,您需要一个窗口。它可能是一个隐藏的窗口,但您确实需要一个。如果没有窗口,则无法处理消息,也无法挂起,因为您只是忽略了所有消息。
  • 因此,如果任务管理器中不包含窗口(这会使我的问题过时),就不可能在任务管理器中出现“无响应”进程?
  • @Xaltar 该进程可能仍有隐藏窗口。使用 spy++ 检查进程以检查窗口句柄。如果它没有,那么是的,它不能是“没有响应”。
  • 那很好。我开始看得更清楚了。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-04
  • 1970-01-01
  • 2012-01-23
  • 1970-01-01
  • 2019-08-12
  • 2011-04-11
  • 1970-01-01
相关资源
最近更新 更多