我有一个程序,希望通过发送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;
}
答案 0 :(得分:5)
处理完第一个事件后,您不会在服务对象上发布任何新工作,因此它会退出。
这意味着然后(在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
。另外,作为一个原则问题,我将first
设为原子(尽管在多个线程上运行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....