Как корректно обработать сигнал SIGKILL в Java

Как делают Вы обрабатываете, моются, когда программа получает сигнал уничтожения?

Например, существует приложение, которое я подключаю к этому, хочет, чтобы любое приложение сторонних производителей (мое приложение) отправило a finish команда, выходя из системы. Что является лучшим, говорят для отправки этого finish управляйте, когда мое приложение будет уничтожено с a kill -9?

редактирование 1: уничтожьте-9, не может быть получен. Спасибо парни для исправления меня.

редактирование 2: Я предполагаю, что этот случай был бы, когда вызовы того просто уничтожают, который совпадает с ctrl-c

106
задан Begui 30 March 2010 в 18:11
поделиться

3 ответа

Это невозможно для любой программы на любом языке, чтобы обработать SIGKILL. Это сделано для того, чтобы всегда можно было завершить программу, даже если она содержит ошибки или злонамеренно. Но SIGKILL - не единственное средство для завершения программы. Другой - использовать SIGTERM. Программы могут обрабатывать этот сигнал. Программа должна обрабатывать сигнал, выполняя контролируемое, но быстрое отключение. Когда компьютер выключается, заключительный этап процесса выключения отправляет каждому оставшемуся процессу сигнал SIGTERM, дает этим процессам отсрочку в несколько секунд, а затем отправляет им сигнал SIGKILL.

Для чего-нибудь , кроме , кроме kill -9 , это можно сделать, зарегистрировав хук shutdown . Если вы можете использовать ( SIGTERM ) kill -15 , ловушка выключения будет работать. ( SIGINT ) kill -2 ДЕЙСТВИТЕЛЬНО заставляет программу корректно завершать работу и запускать обработчики завершения работы.

Регистрирует новую ловушку завершения работы виртуальной машины.

Виртуальная машина Java выключается в ответ на два типа событий:

  • Программа завершается нормально, когда завершается последний недемонический поток или когда вызывается метод exit (эквивалентно System.exit), или
  • Виртуальная машина завершает работу в ответ на прерывание пользователя, такое как ввод ^ C, или общесистемное событие, такое как выход пользователя из системы или завершение работы системы.

Я попробовал следующую тестовую программу на OSX 10.6.3 и на kill -9 он НЕ запускал ловушку выключения, как ожидалось. На kill -15 он ДЕЛАЕТ каждый раз запускает ловушку выключения.

public class TestShutdownHook
{
    public static void main(String[] args) throws InterruptedException
    {
        Runtime.getRuntime().addShutdownHook(new Thread()
        {
            @Override
            public void run()
            {
                System.out.println("Shutdown hook ran!");
            }
        });

        while (true)
        {
            Thread.sleep(1000);
        }
    }
}

Нет никакого способа действительно изящно обработать kill -9 ни в одной программе.

В редких случаях виртуальная машина может прекратить работу, то есть остановить работу без правильного завершения работы. Это происходит, когда виртуальная машина завершает работу извне, например с сигналом SIGKILL в Unix или вызовом TerminateProcess в Microsoft Windows.

Единственный реальный вариант для обработки kill -9 - это заставить другую программу-наблюдатель следить за тем, чтобы ваша основная программа ушла, или использовать сценарий-оболочку. Вы можете сделать это с помощью сценария оболочки, который опрашивал команду ps , ища вашу программу в списке, и действовал соответствующим образом, когда она исчезла.

#!/usr/bin/env bash

java TestShutdownHook
wait
# notify your other app that you quit
echo "TestShutdownHook quit"
123
ответ дан 24 November 2019 в 03:52
поделиться

Есть способов обработки ваших собственных сигналов в определенных JVM - например, см. эту статью о JVM HotSpot .

Используя внутренний вызов метода Sun sun.misc.Signal.handle (Signal, SignalHandler) , вы также можете зарегистрировать обработчик сигнала, но, вероятно, не для таких сигналов, как INT или TERM , поскольку они используются JVM.

Чтобы иметь возможность обрабатывать любой сигнал , вам придется выпрыгнуть из JVM на территорию операционной системы.

Что я обычно делаю (например) для обнаружения ненормального завершения, так это запуска моей JVM внутри сценария Perl, но заставляю сценарий ждать JVM с помощью системного вызова waitpid .

Затем я получаю информацию о выходе из JVM и о причинах выхода и могу предпринять необходимые действия.

13
ответ дан 24 November 2019 в 03:52
поделиться

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

6
ответ дан 24 November 2019 в 03:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: