在SIGINT上正常关闭

时间:2017-07-17 06:10:43

标签: c++ boost signals boost-asio

我想处理来自内核的SIGINT信号,以便调用一个能够巧妙地关闭我的进程的函数 这是一个工作示例,一个线程正在等待信号,然后调用函数handle_stop:

#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>

void handle_stop(const boost::system::error_code& error, int signal_number) {
    std::cout<<"Executing Safe Shutdown"<<std::cout;
    exit(0);
}

int main() {
    std::cout<<"Init"<<std::cout;
    boost::asio::io_service signalService;
    boost::asio::signal_set signals(signalService, SIGINT, SIGTERM, SIGQUIT);
    signals.async_wait(handle_stop);
    boost::thread signalThread(boost::bind(&boost::asio::io_service::run, &signalService));

    std::cout<<"Starting programm"<<std::cout;
    while (true) {
        std::cout<<"Waiting ctl-c"<<std::cout;
        sleep(1);
    }
}

我的目标是在一个类中包含线程和调用的函数来关闭进程。
这是一个非工作尝试,过程立即关闭而不等待信号 有什么问题?

#include <atomic>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>

class Shutdown {
public:
      Shutdown():is_signal_received_ (false) {
              //signals_::remove();
              std::cout<<"constructor"<<std::endl;
      }
      ~Shutdown() {
      }

      void init() {
              std::cout<<"Init "<<std::endl;
              boost::asio::signal_set signals(signalService_, SIGINT, SIGTERM, SIGQUIT);
              signals.async_wait(boost::bind(boost::mem_fn(&Shutdown::handleStop), this, _1, _2));
              boost::thread signalThread(boost::bind(&boost::asio::io_service::run, &signalService_));
              std::cout<<"Init Completed"<<std::endl;
      }

      bool isSignalReceived() const {
              return is_signal_received_;
      }

private:
      std::atomic<bool> is_signal_received_;
      boost::asio::io_service signalService_;

      void handleStop(const boost::system::error_code& error, int signal_number) {
              is_signal_received_ = true;
              myHandleStop(error, signal_number);
      }

      virtual void myHandleStop(const boost::system::error_code& error, int signal_number) {
      }
};

class MyShutdown: public Shutdown {
private:
      void myHandleStop(const boost::system::error_code& error, int signal_number) {
              std::cout<<"Executing Safe Shutdown"<<std::cout;
              exit(0);
      }
};

int main() {
    MyShutdown safeShutdown;
    safeShutdown.init();
    while (true) {
        std::cout<<"Waiting ctl-c"<<std::cout;
        sleep(1);
    }
}

这是编译命令:

  

g ++ -o main main.cpp -lpthread -l boost_thread -l boost_system --std = c ++ 11

1 个答案:

答案 0 :(得分:1)

您的问题是signal_set超出了范围,并在Shutdown::init结束时被销毁。发生这种情况时,async_wait将被取消。 signalThread同时也不在detachjoin之内。那些都需要成为班级成员才能保持活着直到可以处理信号:

#include <atomic>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>

class Shutdown {
public:
    Shutdown()
        : is_signal_received_ (false),
        signalService_(),
        signals_(signalService_, SIGINT, SIGTERM, SIGQUIT)
    {
        std::cout<<"constructor"<<std::endl;
    }
    ~Shutdown()
    {
        signals_.cancel();
        signalService_.stop();
        signalThread_.join();
    }

    void init() {
        std::cout<<"Init "<<std::endl;
        signals_.async_wait(boost::bind(&Shutdown::handleStop, this, _1, _2));
        signalThread_ = boost::thread(boost::bind(&boost::asio::io_service::run, &signalService_));
        std::cout<<"Init Completed"<<std::endl;
    }

    bool isSignalReceived() const {
        return is_signal_received_;
    }

private:
    std::atomic<bool> is_signal_received_;
    boost::asio::io_service signalService_;
    boost::thread signalThread_;
    boost::asio::signal_set signals_;

    void handleStop(const boost::system::error_code& error, int signal_number) {
        is_signal_received_ = true;
        myHandleStop(error, signal_number);
    }

    virtual void myHandleStop(const boost::system::error_code& error, int signal_number) {
    }
};

class MyShutdown: public Shutdown {
private:
    void myHandleStop(const boost::system::error_code& error, int signal_number) {
        std::cout<<"Executing Safe Shutdown"<<std::endl;
        exit(0);
    }
};

int main() {
    MyShutdown safeShutdown;
    safeShutdown.init();
    while (true) {
        std::cout<<"Waiting ctl-c"<<std::endl;
        sleep(10);
    }
}

我还添加了关闭io_servicesignal_set的来电,并等待thread~Shutdown中终止。