【问题标题】:boos::asio async_wait seems to be blockingboost::asio async_wait 似乎正在阻塞
【发布时间】:2016-02-17 20:02:37
【问题描述】:

我正在学习 boost asio 文档。我遇到了这个 deadline_timer 示例。

#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>


/*This timer example shows a timer that fires once every second.*/

void print(const boost::system::error_code& e, boost::asio::deadline_timer* t, int* count)
{
    if (*count < 5)
    {   
        std::cout << *count << std::endl;
        ++(*count);

        t->expires_at(t->expires_at() + boost::posix_time::seconds(1));

        t->async_wait(boost::bind(print,boost::asio::placeholders::error, t, count));
    }   
}

int main()
{
    boost::asio::io_service io; 

    int count = 0;

    boost::asio::deadline_timer t(io, boost::posix_time::seconds(10));

    auto myfunc = boost::bind(print, boost::asio::placeholders::error, &t ,&count);
    t.async_wait(myfunc);

    std::cout << "async wait " << std::endl;

    io.run();

    std::cout << "Just called io.run() " << std::endl;                                                                                                                                                             

    std::cout << "Final count is " << count << std::endl;

    return 0;
}

async_wait() 函数似乎被阻塞(即等待 10 秒计时器到期)

上述程序的输出如下。

async wait 
0
1
2
3
4
Just called io.run() 
Final count is 5

我希望 async_wait() 创建一个单独的线程并在那里等待计时器到期,同时执行主线程。

即我希望程序能够打印

Just called io.run() 
Final count is 5

在等待计时器到期时。?是不是我的理解错了?

这是我对 async_wait() 的理解。这个实现看起来更像blocking wait。我的理解错了吗?我错过了什么?

【问题讨论】:

  • 您期望的输出是什么?从我的角度来看,一切看起来都按照正确的顺序发生。
  • @Xirema - 请查看我对上述问题的编辑。我已经解释了我期望发生的事情。

标签: c++ multithreading boost boost-asio


【解决方案1】:

io.run(); 语句是解释您获得的输出与您期望的输出之间差异的关键。

在 ASIO 框架中,任何异步命令都需要有一个专门的线程来运行回调。但是因为 ASIO 比较低级,所以它希望你自己提供线程。

因此,当您在主线程中调用io.run(); 时,您所做的是向框架指定您打算在主线程上运行所有异步命令。这是可以接受的,但这也意味着程序将阻塞io.run();

如果您打算在单独的线程上运行命令,则必须编写如下内容:

std::thread run_thread([&]() {
    io.run();
});

std::cout << "Just called io.run() " << std::endl;                                                                                                                                                             

std::cout << "Final count is " << count << std::endl;

run_thread.join();

return 0;

【讨论】:

  • @liv2hak 我写了一个lambda expression 来快速模拟线程的创建,而无需构建和绑定函数指针。在这种情况下,[&amp;] 表示我在 lambda 中引用的任何未在本地声明的变量都应该被捕获,特别是通过引用捕获(与 [=] 相反,这意味着我想要按价值捕获)。
【解决方案2】:

async_wait 函数没有阻塞,run 是。那是run 的工作。如果您不希望线程阻塞在 io_service 的处理循环中,请不要让该线程调用 run

async_wait 函数不会创建任何线程。这会使它变得昂贵,并且更难控制服务于 io_service 的线程数。

您的期望是不合理的,因为从main 返回会终止该过程。那么谁或什么会等待计时器呢?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    相关资源
    最近更新 更多