Можно ли установить обещание в обработчике сигнала?

Я искал способ остановить поток, который выполняет задачу каждые 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 Отменить
(ядро сброшено)

Хорошо, нужно позаботиться о том, что он делает в контексте обработчика, но я должен сказать, что не ожидал этого краха; и я не очень понимаю это …
Есть ли у вас какие-либо идеи?

2

Решение

Я полагаю, что у вас есть неопределенное поведение в результате вызова стандартной библиотечной функции (не в списке функций, обеспечивающих безопасность сигнала) в обработчике сигнала.

Ограничения на функцию обработчика сигнала (которая определяется пользователем) являются обширными и задокументировано здесь.

Еще одна вещь, на которую следует обратить внимание, это то, что обработчик сигнала ссылается на какой-либо объект со статическим или локальным потоком (начиная с C ++ 11) сроком хранения, который не является std::atomic(начиная с C ++ 11) или volatile std::sig_atomic_t,

И, как указал @BasileStarynkevitch, если вы работаете в Linux, убедитесь, что только асинхронному сигнал безопасно функции вызываются из обработчика сигнала.

2

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

Других решений пока нет …

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