gpt4 book ai didi

c++ - boost::asio signal_set 处理程序仅在捕获到第一个信号后执行,并忽略相同类型的连续信号

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:44:48 38 4
gpt4 key购买 nike

我有一个程序,我想通过发送 SIGINT 将一些数据写入文件而不是立即退出来停止它。但是,如果程序的用户再次发送 SIGINT,则程序应立即退出并忘记将数据写入文件。

出于可移植性的原因,我想为此目的使用 boost::asio

我最初的(简化的)方法(见下文)没有奏效。这是不可能的还是我遗漏了什么?

处理程序似乎只被调用一次(打印出消息)并且程序总是在循环达到最大迭代次数时停止。

void handler(
const boost::system::error_code& error,
int signal_number) {
if (!error) {
static bool first = true;
if(first) {
std::cout << " A signal(SIGINT) occurred." << std::endl;
// do something like writing data to a file
first = false;
}
else {
std::cout << " A signal(SIGINT) occurred, exiting...." << std::endl;
exit(0);
}
}
}

int main() {
// Construct a signal set registered for process termination.
boost::asio::io_service io;
boost::asio::signal_set signals(io, SIGINT);

// Start an asynchronous wait for one of the signals to occur.
signals.async_wait(handler);
io.run();
size_t i;

for(i=0;i<std::numeric_limits<size_t>::max();++i){
// time stepping loop, do some computations
}

std::cout << i << std::endl;
return 0;
}

最佳答案

当您处理第一个事件时,您不会在服务对象上发布任何新工作,因此它会退出。

这意味着然后(在 ioservice 退出后)紧密循环开始。这可能不是您所期望的。

  1. 如果你想再次监听 SIGINT,你必须等待处理程序再次设置信号:

    #include <boost/asio.hpp>
    #include <boost/asio/signal_set.hpp>
    #include <boost/bind.hpp>
    #include <boost/atomic.hpp>
    #include <iostream>

    void handler(boost::asio::signal_set& this_, boost::system::error_code error, int signal_number) {
    if (!error) {
    static boost::atomic_bool first(true);
    if(first) {
    // do something like writing data to a file
    std::cout << " A signal(SIGINT) occurred." << std::endl;
    first = false;

    this_.async_wait(boost::bind(handler, boost::ref(this_), _1, _2));
    }
    else {
    std::cout << " A second signal(SIGINT) occurred, exiting...." << std::endl;
    exit(1);
    }
    }
    }

    int main() {
    // Construct a signal set registered for process termination.
    boost::asio::io_service io;
    boost::asio::signal_set signals(io, SIGINT);

    // Start an asynchronous wait for one of the signals to occur.
    signals.async_wait(boost::bind(handler, boost::ref(signals), _1, _2));
    io.run();
    return 2;
    }

    如您所见,我将 signal_set& 引用绑定(bind)到处理程序,以便能够在接收到第一个信号后对其进行 async_wait。此外,原则上,我将 first 设为原子(尽管在多个线程上运行 io_service 之前这不是必需的)。

  2. 您真的希望在后台运行 io_service 吗?在这种情况下,让它看起来像这样:

    signals.async_wait(boost::bind(handler, boost::ref(signals), _1, _2));

    boost::thread(boost::bind(&boost::asio::io_service::run, boost::ref(io))).detach();

    while (true)
    {
    std::cout << "Some work on the main thread...\n";
    boost::this_thread::sleep_for(boost::chrono::seconds(1));
    }

    典型输出:

    Some work on the main thread...
    Some work on the main thread...
    Some work on the main thread...
    ^CSome work on the main thread...
    A signal(SIGINT) occurred.
    Some work on the main thread...
    Some work on the main thread...
    ^CSome work on the main thread...
    A second signal(SIGINT) occurred, exiting....

关于c++ - boost::asio signal_set 处理程序仅在捕获到第一个信号后执行,并忽略相同类型的连续信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25530445/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com