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

我有一个程序,想通过发送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退出之后)启动紧密循环.这可能不是您的预期.

>如果您想再次侦听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&引用处理程序,以便在收到第一个信号后能够对其进行async_wait.另外,作为一个原则问题,我首先制作了一个原子(虽然在你在多个线程上运行io_service之前没有必要).
>你真的希望在后台运行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处理程序仅在捕获到第一个信号后执行,并忽略相同类型的连续信号 - 代码日志