boost :: asio :: io_service :: run中的高CPU使用率

时间:2014-07-11 06:12:05

标签: c++ boost boost-asio

我遇到了一个与boost :: asio :: io_service :: run有关的奇怪问题。有时候这个run函数似乎吃掉了整个cpu(100%),有时却没有。我对这种模式不是很清楚。

相关代码:

class Asio {
 public:
  Asio() :
      io_service_(new boost::asio::io_service),
      run_() {}

  void Start() {
    if (!asio_thread_.joinable()) {
      run_ = true;
      asio_thread_ = std::thread([=] {
        Run();
      });
    }
  }

  boost::asio::io_service* io_service() { return io_service_.get(); }

 protected:
  void Run() {
    for (;;) {
      boost::system::error_code ec;
      io_service()->run(ec);

      if (run_) {
        io_service()->reset();
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
      } else {
        break;
      }
    }
  }

 protected:
  std::unique_ptr<boost::asio::io_service>    io_service_;
  std::thread                                 asio_thread_;
  std::atomic<bool>       run_;
};

run函数正常运行时,下面是callstack

#0  0x00000035f74e9163 in epoll_wait () from /lib64/libc.so.6
#1  0x0000000000b3f6ef in boost::asio::detail::epoll_reactor::run(bool, boost::asio::detail::op_queue<boost::asio::detail::task_io_service_operation>&) ()                                       
#2  0x0000000000b40111 in boost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex>&, boost::asio::detail::task_io_service_thread_info&, boost::system::error_code const&) ()
#3  0x0000000000b3feaf in boost::asio::detail::task_io_service::run(boost::system::error_code&) ()
#4  0x0000000000b403fd in boost::asio::io_service::run(boost::system::error_code&) ()
#5  0x0000000000b3ddc1 in Asio::Run() ()

run函数异常时,下面是callstack:

#0  0x00000031bbee53c9 in syscall () from /lib64/libc.so.6
#1  0x00007f831d1d3d68 in std::chrono::_V2::steady_clock::now() () from /usr/local/gcc48/lib64/libstdc++.so.6
#2  0x0000000000b45b6d in boost::asio::detail::chrono_time_traits<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> >::now() ()
#3  0x0000000000b45608 in boost::asio::detail::timer_queue<boost::asio::detail::chrono_time_traits<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> > >::get_ready_timers(boost::asio::detail::op_queue<boost::asio::detail::task_io_service_operation>&) ()
#4  0x0000000000b3f5d7 in boost::asio::detail::timer_queue_set::get_ready_timers(boost::asio::detail::op_queue<boost::asio::detail::task_io_service_operation>&) ()
#5  0x0000000000b3f815 in boost::asio::detail::epoll_reactor::run(bool, boost::asio::detail::op_queue<boost::asio::detail::task_io_service_operation>&) ()                                       
#6  0x0000000000b40111 in boost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex>&, boost::asio::detail::task_io_service_thread_info&, boost::system::error_code const&) ()
#7  0x0000000000b3feaf in boost::asio::detail::task_io_service::run(boost::system::error_code&) ()
#8  0x0000000000b403fd in boost::asio::io_service::run(boost::system::error_code&) ()
#9  0x0000000000b3ddc1 in Asio::Run() ()

在这两种情况下,io_service中都有一些待处理的处理程序,因此io_service::run不应该返回,应该等待事件发生。

欢迎任何建议。

我做了进一步的检查,似乎是由于使用了boost :: asio :: steady_timer。 steady_timer的使用涉及使用以下模式:

boost::asio::steady_timer timer;
timer.expires_at(some_expiry, error_code)
timer.async_wait((=)(boost::system::error_code ec) {
  // some operation
  timer.expires_at(new_expiry, error_code);
  timer.asyn_wait(...);
});

定时器包装在共享指针中,并且可以安全地复制到lamda函数中。

0 个答案:

没有答案