2015-02-06 270 views
0

以下是我在我的服务器中使用的Timer的示例代码。这是一个多线程进程,用于处理大量数据。一旦定时器触发它在处理数据的一些操作和复位本身新的时间重置boost :: deadline_timer导致崩溃的处理程序

class MyTimer 
{ 
    public: 
     MyTimer(boost::asio::io_service& ios):strand_(ios) 
     { 
      for (int i = 0; i < 10; i++) 
      { 
       std::auto_ptr<boost::thread> thread(
         new boost::thread(boost::bind(&boost::asio::io_service::run, 
              &ios_))); 
       thread_pool_.push_back(thread.get()); 
       thread.release(); 
      } 
      boost::posix_time::seconds expTime(10); 
      eodTimer_.reset(new boost::asio::deadline_timer(ios)); 
      eodTimer_->expires_from_now(expTime); 
      eodTimer_->async_wait(boost::bind(&MyTimer::onTimer, this)); 
     }; 

     ~MyTimer() 
     { 
       ThreadPool::iterator it(thread_pool_.begin()); 
       for (; it != thread_pool_.end(); ++it) 
       { 
        (*it)->join(); 
        delete *it; 
       } 
     } 
     void onTimer() 
     { 
      //do some stuff... 
      // reset timer 
      boost::posix_time::seconds expTime(10); 
      eodTimer_->expires_from_now(expTime); 
      eodTimer_->async_wait(boost::bind(&MyTimer::onTimer, this)); 
     } 

    private: 
     boost::asio::io_service ios; 
     boost::asio::strand strand_; 
     boost::scoped_ptr<boost::asio::deadline_timer> eodTimer_; 
}; 

到目前为止,我没有看到这个代码的任何问题。但从几个小时后运行我的服务器崩溃。堆栈跟踪指向我:: onTimer回调处理程序。

#0 0x0a446c06 in boost::asio::detail::timer_queue<boost::asio::time_traits<boost::posix_time::ptime> >::cancel_timer (this=0xe3be0bc, 
    timer_token=0xe9877ec) at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/detail/timer_queue.hpp:141 
#1 0x0a445791 in boost::asio::detail::epoll_reactor<false>::cancel_timer<boost::asio::time_traits<boost::posix_time::ptime> > (this=0xe49f498, 
     timer_queue=..., token=0xe9877ec) at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/detail/epoll_reactor.hpp:424 
#2 0x0a444197 in boost::asio::detail::deadline_timer_service<boost::asio::time_traits<boost::posix_time::ptime>, boost::asio::detail::    epoll_reactor<false> >::cancel (this=0xe3be0a8, impl=..., ec=...) at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/detail/deadline_timer_service.hpp:104 #3 0x0a443f31 in boost::asio::detail::deadline_timer_service<boost::asio::time_traits<boost::posix_time::ptime>, boost::asio::detail::    epoll_reactor<false> >::expires_at (this=0xe3be0a8, impl=..., expiry_time=..., ec=...) 
      at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/detail/deadline_timer_service.hpp:120 
#4 0x0a441e92 in boost::asio::detail::deadline_timer_service<boost::asio::time_traits<boost::posix_time::ptime>, boost::asio::detail::    epoll_reactor<false> >::expires_from_now (this=0xe3be0a8, impl=..., expiry_time=..., ec=...) 
       at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/detail/deadline_timer_service.hpp:137 
#5 0x0a43f895 in boost::asio::deadline_timer_service<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> >::    expires_from_now (
        this=0xe49f438, impl=..., expiry_time=..., ec=...) at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/deadline_timer_service.hpp: 144 
#6 0x0a451d64 in boost::asio::basic_deadline_timer<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime>, boost::asio::  deadline_timer_service<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> > >::expires_from_now (this=0xe9877e8, expiry_time=...) 
         at /vobs/FO_FOX/fo_fx_appl/appl/include/boost/asio/basic_deadline_timer.hpp:297 
#7 0x0a44e941 in fxpay::AggregatorRouter::Impl::MyTimer::onTimer (this=0xe987e48) at MyTimer.cpp:183 

是否有什么错误的方式我使用boost :: dead_line计时器? (我正在使用1.39升级版本)

回答

1

您正在运行10个线程,并且没有对eodTimer的访问进行同步。

deadline_timer对象不是线程安全的,因此您因数据竞争而获取未定义行为。

你的意思是在一条链上运行定时器吗?

+0

我正在使用strand来处理一些其他高频执行的asio任务。为了简单起见,我没有复制代码。在这种情况下,计时器在24小时后过期,并在处理器中重新复位为24小时。并且只有一个计时器对象。我不确定定时器是否存在竞争条件的可能性。纠正我,如果我错了。 – user1545583 2015-02-09 07:00:39

+0

如果不从其他任何其他股线访问定时器,则不适用。在这种情况下,当_“它对已处理的数据进行一些操作”时,您可能会发生数据竞争。但之后我们无法分辨,因为相关代码不在那里。 – sehe 2015-02-09 08:54:52

+0

我以前忘了提及,我应该有。在上面的堆栈跟踪中,当我检查boost :: asio :: detail :: timer_queue中的元素数时,我看到排队为'92'的对象数量,这很奇怪,因为定时器在24小时后重置并且进程正在运行很多天。所有对象都已损坏。有没有人更早观察过这种行为? – user1545583 2015-02-10 04:05:39