SIGINT 正常关闭
Graceful shutdown on SIGINT
我想处理来自内核的 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);
}
}
我的目标是在一个 class 线程和调用关闭进程的函数中打包。
这是一个无效的尝试,进程立即关闭而不等待信号。
怎么了?
#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
您的问题是您的 signal_set
超出范围并在 Shutdown::init
结束时被销毁。发生这种情况时,async_wait
将被取消。 signalThread
也同时超出了范围,没有被 detach
ed 或 join
ed。他们都需要成为 class 成员,这样他们才能在信号被处理之前一直存活:
#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_service
和 signal_set
并等待 thread
在 ~Shutdown
中终止的调用。
我想处理来自内核的 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);
}
}
我的目标是在一个 class 线程和调用关闭进程的函数中打包。
这是一个无效的尝试,进程立即关闭而不等待信号。
怎么了?
#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
您的问题是您的 signal_set
超出范围并在 Shutdown::init
结束时被销毁。发生这种情况时,async_wait
将被取消。 signalThread
也同时超出了范围,没有被 detach
ed 或 join
ed。他们都需要成为 class 成员,这样他们才能在信号被处理之前一直存活:
#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_service
和 signal_set
并等待 thread
在 ~Shutdown
中终止的调用。