Answers:
应用程序从Windows提供的队列中获取事件。
如果应用程序在一段时间(5秒)内没有轮询事件队列(例如进行长时间计算时),则Windows会假定该应用程序已挂起并向用户发出警报。
为了避免这种情况,应用程序应该将昂贵的计算推送到工作线程或拆分处理,并确保定期轮询队列。
GetMessage
(或类似电话)和DispatchMessage
。
IsHungAppWindow
正确回答所接受的答案表示在启动阶段的程序不必调用GetMessage
。
GetMessage
?该功能允许简单的命令行应用程序正常工作而不会被挂起,因为它们不需要轮询队列。
如果没有Windows的源代码,我们将无法确定其内部在做什么。
有一个IsHungAppWindow
可以使用的Windows SDK功能。
如果应用程序未等待输入,未处于启动处理中且未在5秒钟的内部超时时间内调用PeekMessage,则认为该应用程序没有响应。
如果顶级窗口停止响应消息超过几秒钟,则系统认为该窗口没有响应。在这种情况下,系统将隐藏窗口并将其替换为具有相同Z顺序,位置,大小和视觉属性的重影窗口。这使用户可以移动它,调整大小,甚至关闭应用程序。但是,这些是唯一可用的操作,因为应用程序实际上没有响应。
不会。不对应用程序进行轮询,但会给定处理器时间。
Windows有一个调度系统,该调度系统使处理器有时间处理应用程序线程。
调度算法很复杂,并且在Windows Internals,第1部分(第6版)(开发人员参考)中有完整描述。
PeekMessage
。因此,当Windows向应用程序发送消息且五秒钟内未收到信号时,它将应用程序标记为未响应。实际上,在较新的Windows上,如果该窗口未能及时响应用户输入,则该窗口仅被标记为“不响应” -直到我尝试单击或按下某个键或其他操作时,应用程序才能轻松地保持“挂起”状态。分钟内没有“出现”无响应。
实际上,Windows并不总是知道应用程序没有响应。该应用程序必须是带有窗口的交互式应用程序,并且在Windows得出该应用程序没有响应之前,该窗口必须正在接收该应用程序无法处理的消息。
例如,Windows无法知道是否有没有通过命令行运行的没有用户界面的数字运算应用正在执行它的工作,或者陷入了无限循环。
Windows中的交互式图形应用程序通过连续轮询消息队列来接收事件。Windows使用键盘,鼠标,计时器等事件填充此消息队列。如果某个应用程序在一段时间内无法轮询消息队列(5秒钟是IsHungAppWindow()函数文档中提到的超时),则Windows认为该应用程序“挂起”,可以通过更改窗口标题(添加文本“ (无响应)”或本地化版本中的等效文本),如果用户尝试与窗口互动,则将窗口内容显示为灰色。
应用程序可能会以Windows无法识别的方式挂起。例如,一个应用程序可能会继续轮询其消息队列中的消息,而没有对其进行适当的处理,因此,出于所有实际意图和目的,如果Windows不认识到它是无响应的,则它似乎“挂起”。
您问题的答案是是/否。
尽管Windows操作系统可以并且确实通过Windows消息队列中的事件来轮询应用程序,但程序绝对没有义务链接到WinAPI或处理/应答Windows队列。即使回答队列中的消息,也不会告诉Windows程序是否已“锁定”。这是一个指标,但仅此而已。真正的答案要复杂得多。
真正的答案
人们在这里避开实际答案。确定程序是否“无响应”是“ 停止问题 ”的一种变体,这在计算机科学中是无法确定的。简短的解释是,处理器不能充当第三方来观察自己,以确定子例程是否陷入无限循环,什么也不做,而是增加一个将以某个固定的正常数字终止的计数器。这两个都可以认为是紧密闭环的。一个停止,另一个永不终止。甚至您作为一个人,也不知道程序是否实际上在响应,特别是如果它处于紧密闭合的循环中时,您仅知道它是否应该(响应)。
从Windows的角度来看,这两个循环都是“无响应”的。这就是Windows让您选择等待还是终止的原因,因为它无法显示。
因此推论是“为什么Windows知道进程正在响应?” 答案很聪明。在多线程和多进程OS中编译某个进程时,有时甚至在紧密闭环的情况下,编译器可能会添加yield()命令,该命令向处理器提供方便的通知,告知它可以切换到其他正在运行的进程。它“放弃”处理器,然后发生“上下文切换”(称为),使操作系统(包括Windows)能够响应堆栈中的其他事件,其中一些事件包括跟踪进程已响应。
**这并不意味着响应过程将终止。**无限循环内的进程可以产生处理器,从而允许Windows处理其他事件。
在某些Windows程序中,该程序将处理Windows操作系统信号,该信号可以告诉操作系统“正在响应”,但没有任何程序有义务这样做。您甚至可以在Windows的高级语言(例如perl,php,python和Windows)中编写非常简单的CPU占用率,非终止程序,而Windows可能无法检测到它没有终止且没有响应。那时,Windows取决于试探法-CPU负载,内存,在程序“猜测”期间处理器处理的中断次数。再次,此时,Windows必须要求您终止,因为它确实不知道是否应该终止。
另请参阅Viktor的(正确)答案。忽略有关“不响应”是否与无限循环不同的注释。在不通知Windows消息队列的情况下,应用程序可能会或可能不会处理各种消息,中断,循环。处理消息队列只是OS保持计数以尝试猜测进程是否已挂起的多种事件之一。