xia*_*ong 5 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 Code Online (Sandbox Code Playgroud)
当run函数正常运行时,下面是调用堆栈
#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 Code Online (Sandbox Code Playgroud)
当run函数行为异常时,下面是调用堆栈:
#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() ()
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,io_service中都有一些待处理的处理程序,因此io_service::run不应返回,并且应等待事件发生。
任何建议都欢迎。
我做了进一步检查,似乎是由于使用了boost :: asio :: steady_timer。stable_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(...);
});
Run Code Online (Sandbox Code Playgroud)
计时器包装在共享指针中,并且可以安全地复制到lamda函数中。
| 归档时间: |
|
| 查看次数: |
982 次 |
| 最近记录: |