Можно ли установить обещание в обработчике сигнала? - PullRequest
0 голосов
/ 26 октября 2018

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

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

1 Ответ

0 голосов
/ 27 октября 2018

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...