Windows 如何知道程序是否没有响应?

Aru*_*nth 178 windows

Windows 如何知道程序是否没有响应?它是否不断轮询所有正在运行的应用程序?

rat*_*eak 157

应用程序从 Windows 提供的队列中获取事件。

如果应用程序在一段时间(5 秒)内没有轮询事件队列,例如在进行长时间计算时,则 Windows 假定应用程序已挂起并提醒用户。

为了避免应用程序应该将昂贵的计算推送到工作线程或拆分处理并确保队列定期轮询。

  • ↑ 这个。与调度或已接受答案中的建议无关,仅与您是否定期调用“GetMessage”(或类似内容)和“DispatchMessage”无关。 (27认同)
  • @ratchetfreak:大概是在第一次 CreateWindow 调用之前。命令行应用程序完全不同;它们在 ConHost.EXE 中运行,并为它们与 Windows GUI 系统交互。 (4认同)

Dav*_*ill 80

Windows 如何知道程序是否没有响应?

如果没有 Windows 的源代码,我们无法确定它在内部做什么。

有一个IsHungAppWindow可以使用的 SDK Windows 功能。

如果一个应用程序没有等待输入,没有在启动处理中,并且在 5 秒的内部超时时间内没有调用PeekMessage,则认为应用程序没有响应。

IsHungAppWindow 函数

如果顶级窗口停止响应消息的时间超过几秒钟,则系统认为该窗口没有响应。在这种情况下,系统会隐藏窗口并用具有相同 Z 顺序、位置、大小和视觉属性的幻影窗口替换它。这允许用户移动它、调整它的大小,甚至关闭应用程序。但是,这些是唯一可用的操作,因为应用程序实际上没有响应。

关于消息和消息队列的来源


它是否不断轮询所有正在运行的应用程序?

否。应用程序不会被轮询,但会给予处理器时间。

Windows 有一个调度系统,可以为应用程序线程提供处理器时间。

调度算法很复杂,在Windows Internals, Part 1 (6th Edition) (Developer Reference) 中有完整的描述。

  • 不过,这并不是真正的投票,是吗?我认为内部更像是当您调用“PeekMessage”时窗口上的等待句柄会发出信号。因此,当 Windows 向应用程序发送消息并且在五秒内没有收到信号时,它会将应用程序标记为未响应。事实上,在更新的 Windows 上,如果窗口未能及时响应 *用户* 输入,该窗口只会被标记为“无响应”——直到我尝试单击或按下某个键或其他东西,应用程序很容易保持“挂起” " 分钟没有“出现”无响应。 (9认同)
  • 挂起状态不基于 CPU。大多数程序在 99.999% 的时间里都是“挂起”的,什么都不做。 (2认同)
  • @usr 我在哪里说“挂起”取决于 CPU? (2认同)
  • @usr 答案的前半部分是回答“它是否不断地轮询所有正在运行的应用程序?”。下半部分是回答“Windows 如何知道程序是否没有响应?。OP 合二为一地问了两个问题;) (2认同)
  • 您可以删除“关于消息和消息队列”上方的所有内容,因为它对答案没有帮助。Windows 知道应用程序已停止响应,因为它停止发送消息。该应用程序可能正在运行,因为它正在做一些密集的事情而不是发送消息(但那是一个设计不佳的程序)。 (2认同)

Vik*_*oth 32

实际上,Windows 并不总是知道应用程序没有响应。应用程序必须是一个带有窗口的交互式应用程序,并且在 Windows 断定应用程序没有响应之前,窗口必须接收到应用程序无法处理的消息。

例如,Windows 无法知道从命令行运行的没有用户界面的数字运算应用程序是否正在执行其操作,或者是否陷入无限循环。

Windows 中的交互式图形应用程序通过不断轮询消息队列来接收事件。Windows 使用键盘、鼠标、计时器等事件填充此消息队列。如果应用程序在一段时间内未能轮询消息队列(IsHungAppWindow() 函数文档中提到的超时时间为 5 秒),Windows 会认为应用程序“挂起”,它可能通过更改窗口标题(添加文本“ (Not Responding)”或本地化版本中的等效文本)并在用户尝试与窗口交互时使窗口内容变灰。

应用程序可能会以 Windows 无法识别的方式挂起。例如,应用程序可能会继续轮询其消息队列中的消息,而没有对它们进行适当的操作,因此对于所有实际意图和目的,它会显示为“挂起”,而 Windows 没有意识到它没有响应。

  • 根据定义,不响应意味着不处理窗口消息,因此它不适用于服务或控制台应用程序,所以我想说 Windows 总是知道应用程序是否没有响应。你混淆了死锁并且没有响应。 (8认同)

gro*_*taj 10

Windows 是一个操作系统,它监督所有正在运行的程序。

Windows 使用事件与基于窗口的应用程序进行通信。每个程序都有一个线程,不断监听传入的事件并处理它们。例如,当您单击按钮或通知区域图标时,Windows 会生成一个事件并将其提供给适当的进程。然后该过程可以决定如何处理它。

在 Windows 中,与程序的所有交互都是基于事件的,因此当程序长时间不处理传入事件时,这意味着它没有响应。正如@DavidPostill 在他的回答中发现并指出的那样,超时为 5 秒。PeekMessage是从事件队列中获取事件的函数。