Форум русскоязычного сообщества Ubuntu


Считаете, что Ubuntu недостаточно дружелюбна к новичкам?
Помогите создать новое Руководство для новичков!

Автор Тема: Как отловить закрытие программы?  (Прочитано 7229 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн scsiman

  • Активист
  • *
  • Сообщений: 344
    • Просмотр профиля
Re: Как отловить закрытие программы?
« Ответ #15 : 14 Марта 2011, 12:39:20 »
Насколько помню, SIGKILL и SIGSTOP перехватить нельзя.
Dell Studio XPS 16, Ubuntu 16.04 LTS (Home).
HP nx6110, Ubuntu 8.04 LTS => 10.04 LTS (Home).

Оффлайн Goshman

  • Новичок
  • *
  • Сообщений: 10
    • Просмотр профиля
Re: Как отловить закрытие программы?
« Ответ #16 : 19 Марта 2011, 08:49:20 »
Добрый день!

В продолжение темы перхвата сигналов.

В общем научился перехватывать и обрабатывать сигналы. Проблема в том, что при шатдауне система рассылает процессам SIGKILL (его, как и SIGSTOP, обычными средствами перехватить невозможно), а не более мягкие SIGTERM, SIGINT и прочие.

Таким образом, требуется, чтобы при нажатии на кнопку питания компьютера процессу посылался один из мягких сигналов завершения работы. Вижу 2 пути решения:
1) настраивать гном так, чтобы сначала слал SIGTERM, а затем через, например, секунду SIGKILL;
2) повесить на кнопку питания скрипт (как написать скрипт знаю), который сначала шлет моему процессу SIGTERM, а после его завершения шатдаунит систему.
Однако как реализовать хотя бы один из указанных выше путей я не представляю: ни как насторить шатдаун, ни как повесить скрипт на кнопку.

Может есть еще какие-то варианты? Подскажите плис.

Оффлайн Lion-Simba

  • Старожил
  • *
  • Сообщений: 1126
    • Просмотр профиля
Re: Как отловить закрытие программы?
« Ответ #17 : 19 Марта 2011, 10:05:49 »
Проблема в том, что при шатдауне система рассылает процессам SIGKILL (его, как и SIGSTOP, обычными средствами перехватить невозможно), а не более мягкие SIGTERM, SIGINT и прочие.
Хм. Не должно быть так. Вы в этом уверены? Перепроверьте.

Я уже писал выше, что сначала должен прийти SIGTERM, и если программа не успела за отведенное время закрыться - то приходит SIGKILL.
Оказываю индивидуальную платную техподдержку широкого профиля. Обращаться в ЛС или Jabber.

Оффлайн Goshman

  • Новичок
  • *
  • Сообщений: 10
    • Просмотр профиля
Re: Как отловить закрытие программы?
« Ответ #18 : 19 Марта 2011, 11:18:06 »
Хм. Не должно быть так. Вы в этом уверены? Перепроверьте.

Я уже писал выше, что сначала должен прийти SIGTERM, и если программа не успела за отведенное время закрыться - то приходит SIGKILL.

Проверяю следующим образом.
Простенькое приложение
(Нажмите, чтобы показать/скрыть)
перехватывает сигналы и перед завершением пишет в файл номер сигнала.

Если посылаю ему сигнал из терминала, например: pkill -15 myappто все нормально отрабатывается, и в файле появляется соответсвующая строчка.
Если нажимаю на кнопку питания, то в файле пусто.

Оффлайн Lion-Simba

  • Старожил
  • *
  • Сообщений: 1126
    • Просмотр профиля
Re: Как отловить закрытие программы?
« Ответ #19 : 19 Марта 2011, 18:43:32 »
Если посылаю ему сигнал из терминала, например: pkill -15 myappто все нормально отрабатывается, и в файле появляется соответсвующая строчка.
Если нажимаю на кнопку питания, то в файле пусто.
А если вместо кнопки питания использовать
sudo poweroff
?
Оказываю индивидуальную платную техподдержку широкого профиля. Обращаться в ЛС или Jabber.

Оффлайн Goshman

  • Новичок
  • *
  • Сообщений: 10
    • Просмотр профиля
Re: Как отловить закрытие программы?
« Ответ #20 : 19 Марта 2011, 21:43:54 »
А если вместо кнопки питания использовать
sudo poweroff
?
Как и при кнопке питания: не ловит сигнал. В файле строка не добавляется.

Оффлайн Lion-Simba

  • Старожил
  • *
  • Сообщений: 1126
    • Просмотр профиля
Re: Как отловить закрытие программы?
« Ответ #21 : 20 Марта 2011, 08:33:38 »
А если вместо кнопки питания использовать
sudo poweroff
?
Как и при кнопке питания: не ловит сигнал. В файле строка не добавляется.
Презабавно, конечно. Проверил сам - так и есть. Повторяется даже просто при смене (выходе) пользователя.

Говорят, для отлова выхода из системы можно ещё использовать DBus. Но имеющееся поведение с сигналами - не есть хорошо. По идее, надо этот вопрос исследовать и отправить багрепорт.
Оказываю индивидуальную платную техподдержку широкого профиля. Обращаться в ЛС или Jabber.

Оффлайн Goshman

  • Новичок
  • *
  • Сообщений: 10
    • Просмотр профиля
Re: Как отловить закрытие программы?
« Ответ #22 : 20 Марта 2011, 08:53:45 »

Презабавно, конечно. Проверил сам - так и есть. Повторяется даже просто при смене (выходе) пользователя.

Говорят, для отлова выхода из системы можно ещё использовать DBus. Но имеющееся поведение с сигналами - не есть хорошо. По идее, надо этот вопрос исследовать и отправить багрепорт.
Хм, а может тогда на кнопку питания можно как-то скрипт повесить?
Или может есть альтернатива гномовскому менеджеру питания, где процессы завершения работы более гибко настраиваются?
Я бы тогда своему приложению SIGTERM отправил, дождался его завершения и зашатдаунил систему.

Оффлайн Lion-Simba

  • Старожил
  • *
  • Сообщений: 1126
    • Просмотр профиля
Re: Как отловить закрытие программы?
« Ответ #23 : 20 Марта 2011, 12:07:22 »
Или может есть альтернатива гномовскому менеджеру питания, где процессы завершения работы более гибко настраиваются?
Если бы ваше приложение было демоном, можно было бы для него сделать init-скрипт (UpStart, SystemV) и он бы его корректно останавливал бы по выключению системы. А вот для графических приложений правильно всё-таки SIGTERM обрабатываеть...

Вам нужно не "кнопку питания" ловить, а событие "остановка системы", которое может быть инициировано не только нажатием кнопки питания.
Оказываю индивидуальную платную техподдержку широкого профиля. Обращаться в ЛС или Jabber.

Оффлайн Goshman

  • Новичок
  • *
  • Сообщений: 10
    • Просмотр профиля
Re: Как отловить закрытие программы?
« Ответ #24 : 20 Марта 2011, 13:05:21 »
Вам нужно не "кнопку питания" ловить, а событие "остановка системы", которое может быть инициировано не только нажатием кнопки питания.
К сожалению, как ловить событие "остановка системы" я не представляю.
В моем случае остановка ситемы инициируется только кнопкой питания. При этом запущено только одно пользовательское приложение - моя программа (в автозапуске). Гномовская панель отключена, клавиатуры нет.
По DBus погуглил, но ничего вразумительного не нашел. Если бы  ссылочку как с помощью него отлавливать останов системы, то я был бы безмерно счастлив :)

Пользователь решил продолжить мысль 20 Марта 2011, 16:21:02:
Еще одно одно наблюдение: если процесс запущен от рута, то ему при шатдауне сигнал все же отсылается.
В файле появилась строка: 18:14:33 Signal 1 detected
...

Пользователь решил продолжить мысль 20 Марта 2011, 19:04:15:
Поторопился я со своим наблюдением. Не ловится сигнал больше и под рутом. Похоже в тот раз в системе какой-то подвисший процесс был...
« Последнее редактирование: 20 Марта 2011, 19:04:15 от Goshman »

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Re: Как отловить закрытие программы?
« Ответ #25 : 21 Марта 2011, 05:34:11 »
Вы такие смешные =) Всё ловится и работает.
Код: (sig_test.c) [Выделить]
#include <stdio.h>
#include <signal.h>

void sig_action(int sig) {
    FILE *log = NULL;
    if ((log = fopen("shutdown.log", "a+")) != NULL) {
fprintf(log, "Signal %d detected\n", sig);
fflush(log);
fclose(log);
    }
}

int main()
{
    int i;
    for (i = 0; i < 16; ++i)
signal(i, sig_action);
    while (1)
sleep(1);
    return 0;
}
запускать так
gcc sig_test.c -o sig_test
./sig_test &
В вашем примере есть шанс что приложение помирает когда закрывается X.org

Оффлайн hippi90

  • Активист
  • *
  • Сообщений: 433
    • Просмотр профиля
Re: Как отловить закрытие программы?
« Ответ #26 : 21 Марта 2011, 15:06:49 »
Кстати да, если приложение графическое, то нужно сигналы от X-сервера перехватывать.

Оффлайн Goshman

  • Новичок
  • *
  • Сообщений: 10
    • Просмотр профиля
Re: Как отловить закрытие программы?
« Ответ #27 : 21 Марта 2011, 17:43:19 »
Кстати да, если приложение графическое, то нужно сигналы от X-сервера перехватывать.
Можно пример или ссылочку где про это прочитать?

Оффлайн hippi90

  • Активист
  • *
  • Сообщений: 433
    • Просмотр профиля
Re: Как отловить закрытие программы?
« Ответ #28 : 21 Марта 2011, 18:20:02 »
Я в Qt не силен, смотрите документацию по Qt, как она обрабатывает сигналы именно от X-сервера, смотрите документацию от X-сервера, какие он сигналы посылает. В терминологии Х они называются событиями (events).

 

Страница сгенерирована за 0.043 секунд. Запросов: 22.