您如何区分取消和重新触发的提升deadline_timer
How do you discriminate a cancelled from a retriggered boost deadline_timer
当您在运行计时器上调用expires_from_now()
时,计时器被取消,并调用新的计时器。因此,将调用关联的处理程序。在处理程序中很容易区分在已取消和过期的计时器之间。然而,我想知道,是否有办法歧视在过期和重新触发的计时器之间。在这两种情况下,都调用处理程序与error_code operation_aborted
.或者也许我错过了一些细节。
下面的代码生成以下输出:
20120415 21:32:28079507 Main: Timer1 set to 15 s.
20120415 21:32:28079798 Main: Timer1 set to 12 s.
20120415 21:32:28079916 Handler1: Timer 1 was cancelled or retriggered.
20120415 21:32:40079860 Handler1: expired.
这表明处理程序无法实现已取消处理程序的操作,因为重新触发计时器将调用相同的处理程序,从而执行相同的操作。这可能不是预期的行为。
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <iostream>
using namespace boost::posix_time;
using namespace std;
void handler1(const boost::system::error_code &ec)
{
if (ec == boost::asio::error::operation_aborted)
{
cout << microsec_clock::local_time() << " Handler1: Timer was cancelled or retriggered." << endl;
}
else
{
cout << microsec_clock::local_time() << " Handler1: Timer expired." << endl;
}
}
boost::asio::io_service io_service1;
void run1()
{
io_service1.run();
}
int main()
{
time_facet *facet = new time_facet("%Y%m%d %H:%M:%S%f");
cout.imbue(locale(cout.getloc(), facet));
boost::asio::deadline_timer timer1(io_service1, seconds(15));
timer1.async_wait(handler1);
cout << microsec_clock::local_time() << " Main: Timer1 set to 15 s." << endl;
// now actually run the timer
boost::thread thread1(run1);
timer1.expires_from_now(seconds(12));
cout << microsec_clock::local_time() << " Main: Timer1 set to 12 s." << endl;
// here the timer is running, but we need to reset the deadline
timer1.async_wait(handler1);
thread1.join(); // wait for thread1 to terminate
}
我建议创建一个类来包装使用组合的deadline_timer
。取消时,设置一个标志以记住它已被取消。在处理程序中,重置标志。调用expires_from_now()
时不要设置标志。
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <iostream>
class Timer
{
public:
Timer(
const std::string& name,
boost::asio::io_service& io_service
) :
_name( name ),
_timer( io_service ),
_cancelled( false )
{
_timer.expires_from_now( boost::posix_time::seconds(0) );
this->wait();
}
void wait()
{
_timer.async_wait(
boost::bind(
&Timer::handler,
this,
boost::asio::placeholders::error
)
);
}
void cancel() {
_cancelled = true;
_timer.cancel();
}
void restart() {
_timer.expires_from_now( boost::posix_time::seconds(5) );
}
private:
void handler(
const boost::system::error_code& error
)
{
if ( !error ) {
std::cout << _name << " " << __FUNCTION__ << std::endl;
_timer.expires_from_now( boost::posix_time::seconds(5) );
this->wait();
} else if ( error == boost::asio::error::operation_aborted && _cancelled ) {
_cancelled = false;
std::cout << _name << " " << __FUNCTION__ << " cancelled" << std::endl;
} else if ( error == boost::asio::error::operation_aborted ) {
std::cout << _name << " " << __FUNCTION__ << " retriggered" << std::endl;
this->wait();
} else {
std::cout << "other error: " << boost::system::system_error(error).what() << std::endl;
}
}
private:
const std::string _name;
boost::asio::deadline_timer _timer;
bool _cancelled;
};
int
main()
{
boost::asio::io_service ios;
Timer timer1( "timer1", ios );
Timer timer2( "timer2", ios );
boost::thread thread(
boost::bind(
&boost::asio::io_service::run,
boost::ref(ios)
)
);
sleep( 3 );
std::cout << "cancelling" << std::endl;
timer1.cancel();
timer2.restart();
thread.join();
}
示例会话
macmini:stackoverflow samm$ ./a.out
timer1 handler
timer2 handler
cancelling
timer1 handler cancelled
timer2 handler retriggered
timer2 handler
^C
macmini:stackoverflow samm$
我不知道
任何方法,可能没有好的方法可以做到这一点(文档中没有任何内容表明您可以区分这两种情况)。
我认为这是有目的的。将deadline_timer
设置为新的到期时间,可以调用任何以前的处理程序,因为:
- 有时很难判断
- 计时器上是否已经在等待某些东西,因此当您设置到期时间时,很难判断究竟会发生什么;
- 这是防止 sheduled 事件运行两次的简单方法,需要以特殊方式处理另一个错误代码更容易出错。
相关文章:
- 是否需要在 Timer.5 boost::asio 教程中运行新线程?
- libevent是否允许在不同的线程中运行timer/io的回调
- QGraphicsView / Qgraphicsscene Timer事件不起作用
- 使用boost::asio::deadline_Timer实现通用Timer类时出现问题
- 创建 Timer 类时,我应该使用什么数据类型来保存值?(C/C++)
- C++ `Timer` class implementation
- 用c++编写Timer类
- Qt QLCDNumber Timer
- 在 c# 中是否有等效的 boost::timer::cpu_timer
- NachOS timer.cc 构造函数
- 在 c++ 中是否有像 timer 和 timertask 这样的东西,就像 java 一样
- c++计时器,相当于.NET System.Threading.timer
- 开始使用boost-cpu_timer时,错误:“boost::timer::cpu_timer”尚未声明
- 如何从boost::timer::cpu_timer获取以秒为单位的运行时间
- 如何为一些类(如timer类)编写单元测试
- 如何在c++中创建Timer任务
- Boost Timer 24小时格式
- 如何重启boost::timer::cpu_timer
- 在Timer ISR内使用FreeRTOS中的全局值
- Linux c++ timer周期性回调