如何确定应用程序是否没有响应?

如何确定应用程序是否没有响应?

我在 OSX 上有一个应用程序反复进入无响应状态,必须强制终止。我本来希望可以自动完成此操作,但在使用以下程序检查进程时附言我没有看到任何与“无响应”状态相对应的内容。我查看了状态指示器,但应用程序显示为年代无论它是否响应。

state 状态由一串字符给出,例如“RWNA”。第一个字符表示进程的运行状态:

  • I 标记处于空闲状态(休眠时间超过 20 秒)的进程。
  • R 标记可运行的进程。
  • S 标记休眠时间少于 20 秒的进程。
  • T 标记已停止的进程。
  • U 标记进程处于不可中断等待状态。
  • Z 标记一个死亡进程(“僵尸”)。

我如何确定进程是否未响应就像活动管理器那样?


我也对 AppleScript 解决方案持开放态度。

答案1

“无响应”状态不是进程状态,而是进程已停止与窗口管理器/图形引擎通信。它可能被绑定在循环中,挂在套接字、远程文件上,或任何使其返回处理事件的主循环的东西上。窗口管理器注意到事件正在排队,因此将其标记为“无响应”

您可能需要编写一个小型的 X11 程序,向该进程发送虚拟事件,然后在该进程没有响应时将其终止。

答案2

这是一个使用 UI 脚本的 AppleScript,它查找没有响应的进程并将其终止。

它将与 Mavericks 的活动监视器配合使用。但由于这是 UI 脚本,并且活动监视器的 UI 已更改,因此如果不进行一些小修改,它很可能无法与旧版 OS X 配合使用。

tell application "Activity Monitor" to run  --We need to run Activity Monitor
tell application "System Events" to tell process "Activity Monitor"
    tell radio button 1 of radio group 1 of group 1 of toolbar 1 of window 1 to click --Using the CPU View 
    tell outline 1 of scroll area 1 of window 1 -- working with the list 
        set notResponding to rows whose value of first static text contains "Not Responding" -- Looking for Not responding process
        repeat with aProcess in notResponding
            set pid to value of text field 5 of aProcess  -- For each non responding process retrieve the PID 
            if pid is not "" then do shell script ("kill -9 " & pid) -- KILL the PID. 
        end repeat
    end tell
end tell

答案3

(由于太长而无法在评论中容纳,因此将其作为单独的答案发布)

感谢@MatthieuRiegler 提供原始脚本。

这在 10.12.6 上运行良好,并且是对原始脚本的一个小修改(在我进行自己的调查后看到了@CharlieGorichanaz 的评论):


set textToSearchForInProcessName to "Not Responding"

--  Run Activity Monitor 
tell application "Activity Monitor" to activate

tell application "System Events" to tell process "Activity Monitor"
    --  Wait for the Activity Monitor window to open
    repeat until (exists window 1)
        delay 1
    end repeat
    --display notification "Window appeared"

    --  Wait for the Menubar to be present
    repeat until (exists menu 1 of menu bar item "View" of menu bar 1)
        delay 1
    end repeat
    --display notification "Menubar appeared"

    --  Make sure View -> My Processes is selected 
    click menu item "My Processes" of menu 1 of menu bar item "View" of menu bar 1

    --  Click the 'CPU View' button  ( **1 ) 
    click radio button 1 of radio group 1 ¬
        of group 2 of toolbar 1 ¬
        of window 1

    --  Working with the list of processes 
    tell outline 1 of scroll area 1 of window 1
        --  Looking for Not responding process  
        set notResponding to rows whose value of ¬
            first static text contains textToSearchForInProcessName

        repeat with aProcess in notResponding

            --  For each non responding process retrieve the PID 
            set pid to value of text field 1 of aProcess -- ( **2 )

            --  Kill that process using pid 
            if pid is not "" then do shell script ("kill -9 " & pid)
        end repeat
    end tell
end tell

**1 在 macOS 10.12.x 中,工具栏包含一个附加在此处输入图片描述图标,因为按钮组(CPU、内存、能量等)位于 group 2 of toolbar 1而不是group 1 of toolbar 1。如果没有该图标(我尚未在旧版 macOS 中确认),我相信 CPU 等按钮应该位于group 1 of toolbar 1

**2 如果您曾将“活动”列中的 PID 列拖到其他位置,则适用此情况。我已将 PID 列拖到最左侧的位置,因此在此行上,我必须将索引更改为1

set pid to value of text field 1 of aProcess

列从最左边开始编号,从 1 开始。因此,如果需要,请相应地调整上面一行中突出显示的索引。

相关内容