使用许多 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 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何使用许多 OR 动态构建 booleanbuilder 条件

使用许多导入从 xsd 创建类

如何使用for循环许多变量?

使用许多联接优化 sql 选择

为啥要在包上使用许多子项目和依赖项?

使用 DataReader 将许多行集中到列表中