2015-02-06 73 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