Я искал способ остановить поток, который выполняет задачу каждые 2 секунды. Я решил попытаться использовать std :: обещание / будущее так, чтобы поток мог завершиться немедленно, когда обещание установлено.
#include <future>
#include <iostream>
#include <chrono>
#include <csignal>
std::promise<void> stop;
int main() {
std::signal(SIGINT, [] (int) { stop.set_value(); } );
auto future = stop.get_future();
while (future.wait_for(std::chrono::seconds(1)) != std::future_status::ready) {
std::cout << "I'm still there" << std::endl;
}
}
На самом деле это не работает и вылетает таким образом:
$ ./a.out Я все еще там
^ Cterminate вызывается после создания экземпляра ‘std :: system_error’
what (): неизвестная ошибка -1 Отменить
(ядро сброшено)
Хорошо, нужно позаботиться о том, что он делает в контексте обработчика, но я должен сказать, что не ожидал этого краха; и я не очень понимаю это …
Есть ли у вас какие-либо идеи?
Я полагаю, что у вас есть неопределенное поведение в результате вызова стандартной библиотечной функции (не в списке функций, обеспечивающих безопасность сигнала) в обработчике сигнала.
Ограничения на функцию обработчика сигнала (которая определяется пользователем) являются обширными и задокументировано здесь.
Еще одна вещь, на которую следует обратить внимание, это то, что обработчик сигнала ссылается на какой-либо объект со статическим или локальным потоком (начиная с C ++ 11) сроком хранения, который не является std::atomic
(начиная с C ++ 11) или volatile std::sig_atomic_t
,
И, как указал @BasileStarynkevitch, если вы работаете в Linux, убедитесь, что только асинхронному сигнал безопасно функции вызываются из обработчика сигнала.
Других решений пока нет …