Я буферизирую данные, которые периодически сбрасываются. Бывают случаи, когда приложение могло (могло) завершиться, и эти данные должны быть немедленно сброшены независимо от интервала (например, exit(0/1/...)
в каком-то другом модуле и т. Д.)
У меня есть комбинация реализации Drop
и обработки отправки ожидающих данных при вызове drop
. (тривиальный случай, когда предметы элегантно снесены)
impl Drop for AnalyticsSendQueue {
fn drop(&mut self) {
self.flush();
}
}
Насколько я понимаю, я добавил signal_hook:
if let Ok(mut s) = signal_hook::iterator::Signals::new(signal_hook::consts::TERM_SIGNALS) {
let bulk = Arc::clone(&self.bulk);
std::thread::spawn(move || {
for _ in s.forever() {
info!("got a signal");
let _ = bulk.lock().unwrap().send();
std::process::exit(1);
}
});
} else {
info!("error with signals");
}
Согласно моим тестам, этот код не вызывается, когда другой модуль выполняет exit(code)
Например, я создал тривиальный фоновый поток, который засыпает несколько секунд, а затем вызывает exit
. Обработчики не вызываются (хотя они регистрируются, проверяются через ведение журнала и точки останова):
std::thread::spawn(|| {
std::thread::sleep(Duration::from_secs(10));
std::process::exit(0); // handlers aren't invoked
});
Есть ли способ решить эту проблему?
РЕДАКТИРОВАТЬ !!!! Меня больше всего беспокоит, если exit вызывается из какого-то другого модуля, который я не контролирую.
kill -9
немедленно завершает программу, не оставляя никаких шансов на реакцию. - person Cerberus   schedule 20.05.2021kill -9
- person Shepmaster   schedule 20.05.2021SIGKILL
, он не играет, он просто мгновенно убивает процесс, есть альтернативный сигналSIGTERM
, который более мягкий, и программа должна завершиться сама по себе, если она игнорирует его, она продолжает работать, как если бы ничего не случилось. Большинство систем, которые хотят вежливо убить процесс, обычно отправляютSIGTERM
, немного подождите, и, если процесс еще не завершился сам по себе, он предполагает, что он не сотрудничает, иSIGKILL
его. Нет разумного способа избежать прерывания сSIGKILL
. На самом деле, рекомендуется вообще никогда не использоватьkill -9
, но Интернет ... - person Kaihaku   schedule 20.05.2021kill -9
использует вашу программу, он не заботится о последствиях, как и программист, пишущий код. Это просто выходит за рамки, так же как вы выдергиваете вилку из своего компьютера. Все системы, которые имеют значение, прежде всего, устойчивы к отключениям электроэнергии, и это правильный способ решить проблему - не позволять отключать питание, не предполагать, что питание может отключиться в любой момент. - person Kaihaku   schedule 20.05.2021std::process::exit
(по крайней мере, в Linux), - это вызов libcexit
, поэтому, по-видимому, вы могли бы вызватьlibc::atexit
и передать ему указатель на функцию, но я ничего не знаю вstd
- person trentcl   schedule 20.05.2021atexit
, тогда неконтролируемый код в вашем процессе может выполнить оболочкуkill
программы командной строки и убить себя. Еще проще - позвонитьstd::process::abort()
. Вы не можете помешать кому-то, кто намерен остановить программу. Таким образом, моя точка зрения об отключении питания - если вы устойчивы к неожиданным выходам, то все, что выходит за рамки этого, просто улучшает производительность. - person Shepmaster   schedule 20.05.2021