boost::asio-signal_set处理程序仅在捕获第一个信号后执行,并忽略相同类型的连续信号
boost::asio signal_set handler only executes after first signal is caught and ignores consecutive signals of the same type
我有一个程序,希望通过发送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
。此外,原则上,我将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....
相关文章:
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 如何在没有信号的情况下从C++执行QML插槽
- 调试和自由执行中的信号处理
- 为什么我的信号处理程序只执行一次?
- C++ 在信号处理程序后继续执行
- 当再次触发信号时,从Qt插槽执行的功能被第二次调用时会发生什么?
- QT-执行QTimer :: timout()信号导致QEVENT
- 为什么执行socket :: readyread()的新信号,即使其较早的插槽仍在处理
- 执行 Qt::QueuedConnection 信号始终按顺序调用
- boost:线程未执行接收信号后发布的处理程序
- Qt信号发射和QThread执行流程
- Qt捕获复选框的信号以执行操作
- boost::asio-signal_set处理程序仅在捕获第一个信号后执行,并忽略相同类型的连续信号
- 在c++中用信号改变std::线程的执行流程
- 信号执行期间的 SIGProc掩码
- Qt::QueuedConnection的信号执行顺序
- Qt不需要的双执行按钮按下的信号
- 执行后,信号SIGCHLD不再是SIG_IGN,即使它之前是SIG_IGN
- 如何使用信号来执行任何带参数的函数
- 根据信号和返回地址改变程序执行流程