Разница между выходом и убийством в переполнении стека

Я написал обработчик сигнала для обработки SIGи я хочу убить процесс, если получу слишком много. Итак, какой из следующего кода лучше, или я должен использовать их оба?

  1. exit(-1); // or some other exit code
  2. kill(getpid(), SIGKILL);

0

Решение

Разница между выходом и уничтожением в C ++

Одно отличие состоит в том, что kill функция не указана в стандартной библиотеке C ++. Это просто указано в POSIX. exit это стандартный C ++.

Другое отличие состоит в том, что kill(getpid(), SIGKILL) приведет к тому, что операционная система принудительно завершит процесс. exit вместо этого выполняет очистку (вызывая atexit обратный вызов, очистка потоков и т. д.) и прекращает выполнение добровольно.

Итак, какой из следующего кода лучше, или я должен использовать их оба?

Зависит от варианта использования, но обычно exit является более разумным, так как обычно требуется очистка, которую он обеспечивает.

2

Другие решения

Вы, вероятно, не хотите ни того, ни другого, но то, что вы хотите, гораздо ближе к 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 так что вы можете чистить вещи и изящно выходить.

4

Я бы посоветовал exit(1),

Как правило, приложение хотело бы закончить изящно, если это вообще возможно. SIGKILL это мгновенная смерть для вашего процесса — например, ваши обработчики выхода не будут вызываться. Но в вашем случае вы также должны позвонить getpid так же хорошо как kill сам. exit немедленно инициирует процесс постепенного выхода. Это правильный выбор для ваших нужд.

Там редко хороший архитектурный причина использовать SIGKILL в целом. есть так много сигналов (http://man7.org/linux/man-pages/man7/signal.7.html в POSIX у вас есть SIGINT, SIGTERM, …) и повторять, нет причин не умереть изящно, если сможешь.

1
По вопросам рекламы [email protected]