Я написал обработчик сигнала для обработки SIG
и я хочу убить процесс, если получу слишком много. Итак, какой из следующего кода лучше, или я должен использовать их оба?
exit(-1); // or some other exit code
kill(getpid(), SIGKILL);
Разница между выходом и уничтожением в C ++
Одно отличие состоит в том, что kill
функция не указана в стандартной библиотеке C ++. Это просто указано в POSIX. exit
это стандартный C ++.
Другое отличие состоит в том, что kill(getpid(), SIGKILL)
приведет к тому, что операционная система принудительно завершит процесс. exit
вместо этого выполняет очистку (вызывая atexit
обратный вызов, очистка потоков и т. д.) и прекращает выполнение добровольно.
Итак, какой из следующего кода лучше, или я должен использовать их оба?
Зависит от варианта использования, но обычно exit
является более разумным, так как обычно требуется очистка, которую он обеспечивает.
Вы, вероятно, не хотите ни того, ни другого, но то, что вы хотите, гораздо ближе к exit
чем kill
,
kill
что-то еще приходит извне и насильственно разрушает процесс. exit
сам процесс решает прекратить выполнение. Последнее, как правило, предпочтительнее.
Что касается почему exit
неправильный ответ: большая часть кода C ++ зависит от деструкторов для очистки объектов при выходе из области видимости. Если вы позвоните exit
обычно этого не происходит — вы вызываете exit, он выходит в ОС, и между ними не вызывается никаких деструкторов (кроме тех, которые зарегистрированы в onexit
).
Вместо этого вы, как правило, хотите выдать исключение, которое обычно попадает только в main
и выходит изящно, когда он пойман:
int main() {
try {
do_stuff();
}
catch(time_to_die const &) {
}
}
Преимущество в этом случае заключается в том, что когда вы делаете throw time_to_die;
, он автоматически раскручивает стек, выполняя деструкторы для всех локальных объектов. Когда он вернется к main
вы получаете нормальный выход со всеми выполненными деструкторами, поэтому (при условии правильного использования RAII) все ваши файлы, сетевые соединения, соединения с базой данных и т. д. были закрыты, как и ожидалось, все кэши сброшены и т. д. получить красивый, изящный выход.
Краткое резюме: как правило, код C ++ никогда не должен вызывать exit
, Если ваш код полностью застрял в трещине, и вы хотите выйти немедленно, вы хотите позвонить abort
, Если вы хотите полунормальный выход, сделайте это, выдав исключение, которое вернет вас к main
так что вы можете чистить вещи и изящно выходить.
Я бы посоветовал exit(1)
,
Как правило, приложение хотело бы закончить изящно, если это вообще возможно. SIGKILL
это мгновенная смерть для вашего процесса — например, ваши обработчики выхода не будут вызываться. Но в вашем случае вы также должны позвонить getpid
так же хорошо как kill
сам. exit
немедленно инициирует процесс постепенного выхода. Это правильный выбор для ваших нужд.
Там редко хороший архитектурный причина использовать SIGKILL в целом. есть так много сигналов (http://man7.org/linux/man-pages/man7/signal.7.html в POSIX у вас есть SIGINT, SIGTERM, …) и повторять, нет причин не умереть изящно, если сможешь.