将 boost::asio::signal_set 与 SIGTERM 或 SIGSEGV 一起使用

问题描述 投票:0回答:1

有 signal_set 捕获 SIGTERM 或 SIGINT 的示例。同时注册 SIGABRT 甚至 SIGSEGV 是否被认为是安全的?因为 signal_set 需要 io_context,所以我不确定当 SIGSEGV 发生时该上下文是否仍然有效。

另外,我不确定是否使用 signal_set 注册 SIGTERM 或 SIGINT,以及使用普通 std::signal 注册 SIGSEGV。该文档指出不可能多次注册信号。是否禁止在调用 signal_set 之后调用 std::signal ?

c++ boost boost-asio
1个回答
0
投票

您正确地持有SEGV无法恢复的直觉。至少,程序无法恢复(最好的情况,尝试这样做将导致重复的SEGV)。

您还正确地注意到,如果您已经使用 Asio 的支持,则不应直接干预 POSIX 信号接口。

其余的都定义得很明确:

  • 具有多个信号集
  • 在不同的集合中多次处理信号
  • 多次等待同一组

这里是强制使用 SEGV 6s 的演示:

住在Coliru

#include <boost/asio.hpp>
namespace asio = boost::asio;
using namespace std::chrono_literals;
using std::this_thread::sleep_for;

struct Demo {
    Demo(asio::any_io_executor ex, char const* name) : set(ex), name(name) {
        for (int num : {SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGHUP, SIGPIPE, SIGSEGV})
            set.add(num);
        wait_loop();
    }

  private:
    asio::signal_set set;
    char const*      name;

    using error_code = boost::system::error_code;

  public:
    void wait_loop() {
        set.async_wait([this](error_code ec, int num) {
            printf("%6s signal %s (%s)\n", name, ec.message().c_str(), ::strsignal(num));
            sleep_for(200ms);

            if (num != SIGTERM)
                wait_loop();
        });
    }
};

int main() {
    asio::thread_pool p;

    auto ex = p.get_executor();
    Demo first(ex, "first");
    Demo second(ex, "second");

    second.wait_loop(); // doubly await the second set for good measure

    sleep_for(6s);
    static void (*force_segv)() = nullptr;
    force_segv();

    p.join();
}

交互式现场演示:

© www.soinside.com 2019 - 2024. All rights reserved.