Ubuntu не отправляет SIGTERM при выключении

21

Я начинаю подозревать, что Ubuntu не сообщает запущенным приложениям, что оно закрывается, чтобы позволить им корректно завершить работу, а вместо этого заставляет их завершать работу.

Если я оставляю Chrome открытым при выключении, он говорит, что он не закрывался правильно в последний раз, когда я снова открываю его после загрузки, LibreOffice не спрашивает меня, хочу ли я сохранить свой документ, и я делаю приложение, которое должно запустить некоторый код при выходе, но не разрешается делать это, когда компьютер выключен.

Насколько я понял, SIGTERM сначала отправляется всем процессам, чтобы позволить им завершить работу корректно, а если они не выходят, SIGKILL отправляется, чтобы заставить их выйти. Похоже, что Ubuntu либо вообще не отправляет SIGTERM, либо не дает приложениям достаточно времени для отправки SIGKILL.

Есть ли способ, как я могу это исправить?

Я использую Ubuntu 16.04, но проблема существовала и в 15.10. Я не могу сказать, было ли это там раньше, так как я начал использовать Ubuntu, когда 15.10 была самой новой версией.

Редактировать: я использую Unity и выключаю компьютер, нажимая на шестерню в правом верхнем углу и выбирая выключение, хотя проблема та же, если работать sudo haltв терминале.

Изменить: я наблюдаю то же поведение, когда только выход. Я предполагаю, что сигнал должен быть отправлен при выходе из системы и, следовательно, проблема возникает при завершении работы и выходе из системы.

GKraft
источник
Как ты выключаешься?
тердон
1
Chromium и LibreOffice работают не с SIGTERM так, как вы хотели бы, чтобы это было сделано
Андреа Корбеллини
2
Я не уверен, что понимаю, что вы имеете в виду. Вы имеете в виду, что они неправильно обрабатывают SIGTERM? Возможно, они этого не делают, но, как я написал в своем вопросе, я работаю над программой, которая обрабатывает SIGTERM, но этот код никогда не запускается. SIGINT при нажатии Ctrl + C работает отлично. Я по-прежнему считаю, что существует некоторая проблема, связанная с уведомлением Ubuntu о запущенных процессах при завершении работы.
GKraft
1
Может быть, связано с этой ошибкой: # 1448259 Systemd не отправляет SIGTERM первым при завершении работы ?
JonasCz - Восстановить Монику
2
Раздражает необходимость закрывать все приложения вручную, а что если вы забудете свернутое приложение? Это не спасет вашу работу. И есть много фоновых процессов, которые вы либо не можете легко контролировать, либо не думаете о них. Им не будет предоставлена ​​возможность убирать за собой или спасать то, что они делали.
GKraft

Ответы:

3

К сожалению, это не совсем так работает. Многие из тех программ, которые действительно имеют обработчик сигнала, не блокируют сигнал, чтобы показать диалоговое окно подтверждения. Обработка сигналов часто минимальна или отсутствует.

Вы можете легко попробовать это без необходимости выключения. Просто отправьте SIGTERM вашему запущенному процессу Firefox или LibreOffice:

$ pkill firefox

Обычно Firefox может спросить, действительно ли вы хотите закрыть его. Кроме того, обычно требуется некоторое время для закрытия, особенно когда он работает в течение длительного времени и использует более 1 ГБ ОЗУ - процесс, как правило, занимает около минуты, чтобы завершить процесс после закрытия его последнего окна. Ничего этого не происходит, когда вы отправляете SIGTERM, процесс просто мгновенно завершается.

Однако в некоторых средах рабочего стола все закрытые окна закрываются перед выключением. В отличие от SIGTERM, закрытие окна программно похоже на нажатие кнопки X этого окна или Alt+ F4. Это также то, что делает скрипт в другом ответе - он использует wmctrl, чтобы изящно закрыть все открытые окна.

Когда окно закрыто, программа не спешит и может закрыть все внутри этого окна, например, открыть вкладки, а также может показать диалоговое окно, если есть несохраненная работа. Как только все открытые окна приложения закрываются, процесс обычно завершается вскоре после этого.

Так что это зависит от среды вашего рабочего стола (при условии, что вы используете его для выключения, а не для его работы sudo poweroff). Например, KDE должен дождаться закрытия открытых окон, прежде чем завершать работу, а MATE - нет.

Итог: закройте все открытые окна вручную перед выключением. Или используйте среду рабочего стола, которая ожидает закрытия всех окон.

c0xc
источник
Я вижу, что процесс выключения и обработка сигналов не работают точно так, как я думал. Теперь я понимаю, как это должно работать и почему это не сработало, как я ожидал.
GKraft
0

Для чего это стоит, некоторое время назад я нашел эту процедуру на форуме Манджаро:

close_apps () {
WIN_IDs=$(wmctrl -l | grep -vwE "Desktop$|xfce4-panel$" | cut -f1 -d' ')
for i in $WIN_IDs; do wmctrl -ic "$i"; done

# Keep checking and waiting until all windows are closed
while [ "$WIN_IDs" != "" ]; do
        sleep 0.1;
        WIN_IDs=$(wmctrl -l | grep -vwE "Desktop$|xfce4-panel$" | cut -f1 -d' ')
done

}

Вы можете вызвать его в своем собственном скрипте, чтобы закрыть все открытые приложения до завершения работы (или перезапустить).

Единственная проблема заключается в том, что он был создан для Xfce, поэтому ему нужны изменения, которые вносит Unity DE. Сюда придет небольшая помощь от кого-то более знающего, чтобы помочь решить проблему ОП.

SR
источник
У меня не будет доступа к моему компьютеру в течение нескольких дней, поэтому я не могу попробовать его, даже если он исправлен. Действительно ли необходимо использовать такой скрипт? Я думаю, что Ubuntu Shoukd справиться с этим самостоятельно.
GKraft
Согласовано. Тем не менее, он отлично работает в Xubuntu. Например, завершение работы будет ждать бесконечно, если есть несохраненный документ.
SR
0

На самом деле, часть скрипта, которая закрывает все окна и не зависит от какой-либо конкретной DE, доступна на Ask. 2-й и 3-й ответы особенно полезны. С помощью всего лишь нескольких строк и создав панель запуска на панели или на рабочем столе, вы можете добиться изящного завершения работы, которое работает в DE, который вы используете.

Как закрыть все открытые окна изящно

SR
источник
Они кажутся многообещающими. Я, вероятно, в конечном итоге использовать аналогичный скрипт.
GKraft