使用许多 boost::asio::deadline_timer [重复]
Posted
技术标签:
【中文标题】使用许多 boost::asio::deadline_timer [重复]【英文标题】:Using many boost::asio::deadline_timer [duplicate] 【发布时间】:2015-12-02 09:52:20 【问题描述】:假设我们有一个运行多个网络客户端的应用程序,它们形成一个循环:发送一个请求,然后暂停指定时间,然后再一次。
示例(并非所有代码):
#define WAIT_INTERVAL 1000
class client()
public:
explicit client(boost::asio::io_service & io_service)
: io_service_(io_service)
working_ = true;
;
run(boost::asio::yield_context t_yield)
while (working_)
// async wait
boost::asio::deadline_timer timer(io_service_, boost::posix::milliseconds(WAIT_INTERVAL));
timer.async_wait(t_yield);
do_work();
;
private:
void do_work()
// make work
bool working_ false ;
boost::asio::io_service & io_service_;
class app()
public:
// code omitted
prepare(size_t number_of_clients)
clients_.reserve(number_of_clients);
for (size_t i = 0; i < number_of_clients; ++i)
clients_.emplace_back(io_service_);
run()
for (auto & client : clients_)
boost::asio::spawn(io_service_, [&client](boost::asio::yield_context t_yield)
client.run(t_yield);
);
private:
boost::asio::io_service io_service_;
std::vector<client> clients_;
问题是:当运行许多客户端(比如 100 个左右)时,deadline_timer
实际上会等待几秒钟,不是接近 1000 毫秒,而是大约 9000 毫秒甚至更多。
如何避免这种情况或如何重写程序,以便每个客户端将等待给定的等待间隔加减一些小的差异?
【问题讨论】:
@RichardHodges 谢谢你,Richard,但问题不在于如何实现异步客户端和服务器。请在回答之前阅读问题。 不客气,但如果没有异步解决方案,您将无法在超时的情况下取得任何进展;) @RichardHodges 我的代码正是基于这些示例。当客户端数量较少时,它(计时器)可以正常工作。但是当客户数量很大(100+)时,他们等待的时间太长了。您是否知道如何为如此多的客户实施超时?或者你能指出具体的例子吗? 好的,我想这里的问题是“延迟发生在哪里?”。计时器的处理程序将通过 io_service 队列执行。如果加载了该队列,则计时器事件将不得不等待轮到它们。会不会是客户所做的工作没有得到足够的回报?没有指标就很难推测... 【参考方案1】:只是不要等待定时器到期,而是传递一个处理程序以在定时器到期时调用。在 ASIO 应用程序中,唯一的阻塞调用应该是io_service::run()
。
【讨论】:
如果我用handler把它改成timer.async_wait
,结果是一样的。
我更改了有问题的代码。
您确定您的服务器没有承受过多的 CPU 负载吗?
抱歉,您的服务器正忙于循环所有连接。只是不要那样做。异步处理所有内容并生成所需数量的线程,只需调用io_service_.run()
。
抱歉,我在简化代码时忘记了。更新为实际使用(使用 spawn 和 yield)。 CPU 负载约为 2-4%。以上是关于使用许多 boost::asio::deadline_timer [重复]的主要内容,如果未能解决你的问题,请参考以下文章