是否可以在信号处理程序中设置承诺?

Ozn*_*nOg 2 c++ signal-handling promise c++11

我正在寻找一种方法来停止每 2 秒执行一次任务的线程。我决定尝试使用 std::promise/future 以便在设置承诺时线程可以立即退出。

#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;
    }
}
Run Code Online (Sandbox Code Playgroud)

实际上这不起作用并以这种方式崩溃:

$ ./a.out 我还在那里 ^Cterminate 在抛出一个 'std::system_error'
what()实例后被调用:未知错误 -1 放弃(核心转储)

好的,一个人应该注意他在处理程序上下文中所做的事情,但我必须说我没有预料到这次崩溃;我真的不明白……你有什么想法吗?

P.W*_*P.W 5

我相信您在这里拥有的是未定义的行为,因为在信号处理程序中调用了标准库函数(不在信号安全函数列表中)。

对信号处理函数(即用户定义)的限制非常广泛,并在此处记录

另一件需要注意的事情是,信号处理程序是否引用了任何具有静态或线程局部(C++11 起)存储持续时间的对象,而不是std::atomic(C++11 起)或volatile std::sig_atomic_t.

正如@BasileStarynkevitch 指出的那样,如果您使用的是 Linux,请确保仅从信号处理程序调用异步信号安全函数。