Как я могу определить, что приложение не отвечает?
У меня есть приложение на OSX, которое постоянно переходит в состояние "Не отвечает" и должно быть принудительно уничтожено. Я надеялся автоматизировать его, но при проверке процесса с помощью ps я не вижу ничего, что соответствовало бы состоянию Not Responding. Я посмотрел на индикатор состояния, но приложение показывает как S, отвечает ли он или нет.
состояние Состояние задается последовательностью символов, например, ``RWNA''. Первый символ указывает состояние выполнения процесса:
- I Отмечает процесс, который простаивает (спит дольше, чем около 20 секунд).
- R отмечает исполняемый процесс.
- S Отмечает процесс, который спит менее 20 секунд.
- T отмечает остановленный процесс.
- U отмечает процесс в непрерывном ожидании.
- Z отмечает мертвый процесс ("зомби").
Как определить, не отвечает ли процесс, как это делает Менеджер активности?
Я также открыт для решений AppleScript.
3 ответа
Состояние "Не отвечает" - это не состояние процесса, а процесс прекратил связь с оконным менеджером / графическим ядром. Это может быть связано в цикле, висящем на сокете, удаленном файле, чем угодно, что заставляет его возвращаться в основной цикл, который обрабатывает события. Диспетчер окон замечает, что события находятся в очереди, и поэтому помечает его как "Не отвечающий".
Вам может потребоваться написать небольшую программу X11, которая отправляет фиктивные события процессу, а затем убить ее, если она не отвечает.
Вот AppleScript, использующий сценарии пользовательского интерфейса, который ищет не отвечающий процесс и убивает их.
Он будет работать с монитором активности Mavericks. Но поскольку это сценарии пользовательского интерфейса и пользовательский интерфейс Activity Monitor изменился, он, скорее всего, не будет работать со старой 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
(Размещать это как отдельный ответ, так как слишком долго, чтобы уместиться в комментарии)
Благодарим @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, Memory, Energy и т. д.) находится в group 2 of toolbar 1
вместо group 1 of toolbar 1
, В отсутствие этого значка (я не подтвердил в старых версиях macOS), я думаю, что кнопки CPU и т. Д. group 1 of toolbar 1
**2 Это применимо, если вы когда-либо перетаскивали столбец PID в столбце Activity в другую позицию. Я перетащил столбец PID в крайнее левое положение, поэтому в этой строке мне пришлось изменить индекс на 1
:
set pid to value of text field 1 of aProcess
Столбцы пронумерованы слева, начиная с 1. Поэтому при необходимости измените подсвеченный индекс в строке выше.