我想知道一个进程(以QProcess类启动)是否不再响应。例如,我的进程是一个每秒只打印1个的应用程序。
我的问题是,我想知道(出于一些神秘的原因),这个过程是在短时间内被阻止的(超过1秒,人类会注意到这一点)。
但是,QProcess(未运行,正在启动,正在运行)的不同状态不包含“已阻止”状态。
当我们在任务管理器中收到“无响应”消息时,我的意思是阻止为“不要回答操作系统”。例如当Windows MMI(如explorer.exe)被阻止并变为白色时。
但是:我想检测任何进程的“无响应”状态。不只是MMI。
有没有办法检测到这种状态?
答案 0 :(得分:1)
Qt没有为此提供任何api。您需要使用特定于平台的机制。在某些平台上(Windows!),没有挂起的应用程序的概念,只有挂起的窗口。您可以拥有一个同时具有响应和无响应窗口的应用程序:)
在Windows上,您使用EnumWindows
枚举所有窗口,通过比较GetWindowThreadProcessId
到process->pid()
的pid来检查它们是否属于您的流程,最后检查窗口是否为挂过IsHungAppWindow
。
一般来说,没有“无响应”过程的无所不包的概念。
假设您有一台Web服务器。它没有响应是什么意思?它负载很重,因此它可能会拒绝一些传入的连接。从您的角度来看,这是“无回应”吗?它可能是,但你无能为力 - 杀死并重新启动进程将无法修复它。如果有的话,它会使已经连接的客户端变得更糟。
假设您有一个阻止文件系统读取的进程,因为它尝试访问的特定驱动器运行缓慢或负载很重。这是否意味着它没有响应?杀死并重新启动它总能解决这个问题吗?如果该过程然后重试从文件开头的读取,则可能会使事情变得更糟。
假设您的GUI设计过程很差。它正在阻止GUI线程中的串行端口读取。读取它需要很长时间,并且GUI几秒钟内没有响应。你杀了这个过程,它会重新启动并再次尝试读长时间 - 你只会让事情变得更糟。
你必须非常小心地 。
有多种方法可以确定什么是“响应”过程。已经提到过,具有GUI的进程由Windows和OS X上的操作系统监视。因此,可以使用可以查询窗口或进程是否挂起的本机API。这对于提供UI的应用程序很有意义,并且需要注意上述内容。
如果流程正在提供服务,您可以定期使用该服务来确定它是否仍然可用,但需遵守一些截止日期。关于如何处理“挂起”过程的任何选举都应该考虑到系统的CPU和I / O负载。
保留服务对服务请求的响应延迟的历史记录可能是值得的。只应将延迟的“大”变化视为问题的指示。假设您正在跟踪平均延迟。人们可以设定最终截止日期为之前平均延迟的50倍。在这个截止日期之前,该服务被推定为死亡,并被强制回收。 “行动标志”截止日期可以设置为平均等待时间的5-10倍。然后,人们将获得有序重启服务的选项。当等待时间缩短到比触发旗帜的截止日期低30%时,该标志将自动被删除。
如果您是受监控流程的开发人员,那么您可以反转监控方面,并成为受监控流程的被动监督者。然后,受监控的进程必须定期,主动“唤醒”监视器以指示它处于活动状态。唤醒信号的发射(通用术语)应在代码中的战略位置执行。定期接收唤醒“信号”应该允许您推断该过程仍然存在。您可能有多个唤醒信号,标记有观察过程中的位置。一切都取决于流程有多少线程,它在做什么等等。