示例代码如下:

#include <iostream>
#include <boost/asio/io_service.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/asio.hpp>
#include <thread>

typedef std::shared_ptr<boost::asio::steady_timer> timer_ptr;

namespace net = boost::asio;
using tcp = boost::asio::ip::tcp;

void executeMission(timer_ptr asio_steady_timer)
{
    asio_steady_timer->expires_from_now(std::chrono::seconds{3});
    asio_steady_timer->async_wait(
        [asio_steady_timer](const boost::system::error_code &ec)
        {
            std::cout<<"excute mission"<<std::endl;
            executeMission(asio_steady_timer);
        }
    );
}

int main()
{
    net::::io_context io_ctx;
    auto asio_steady_timer = std::make_shared<net::steady_timer>(net::make_strand(io_ctx),
                std::chrono::seconds{3});
    executeMission(asio_steady_timer);
    std::cout<<"start io_service"<<std::endl;

    io_ctx.run();

    return 0;
}

编译:

g++ 05.cpp -o 05 -std=c++11 -I /usr/local/boost_1_75_0/include/ -L /usr/local/boost_1_75_0/lib/libboost_thread.a -lpthread

疑问:
有些小伙伴会问lamda表达式像上面那样循环嵌套会导致堆栈变大么?
答案:不会,把lamda表达式想象成函数指针就好理解了,每当触发之后函数指针就被存到别的地方了,原函数就出栈了。所以使用C++11或boost可以放心地让各种async_系列的函数嵌套起来。官方给出的样例很多也是这种写法。如果你还不放心,把程序跑几十秒,然后用pstack看看。结果如下:

$ pstack 40656
#0  0x00007f37c2d8f5e3 in __epoll_wait_nocancel () from /lib64/libc.so.6
#1  0x000000000040875c in boost::asio::detail::epoll_reactor::run(long, boost::asio::detail::op_queue<boost::asio::detail::scheduler_operation>&) ()
#2  0x0000000000409b84 in boost::asio::detail::scheduler::do_run_one(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&, boost::asio::detail::scheduler_thread_info&, boost::system::error_code const&) ()
#3  0x0000000000409726 in boost::asio::detail::scheduler::run(boost::system::error_code&) ()
#4  0x0000000000409f25 in boost::asio::io_context::run() ()
#5  0x0000000000402c25 in main ()
$ pstack 40656
#0  0x00007f37c2d8f5e3 in __epoll_wait_nocancel () from /lib64/libc.so.6
#1  0x000000000040875c in boost::asio::detail::epoll_reactor::run(long, boost::asio::detail::op_queue<boost::asio::detail::scheduler_operation>&) ()
#2  0x0000000000409b84 in boost::asio::detail::scheduler::do_run_one(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&, boost::asio::detail::scheduler_thread_info&, boost::system::error_code const&) ()
#3  0x0000000000409726 in boost::asio::detail::scheduler::run(boost::system::error_code&) ()
#4  0x0000000000409f25 in boost::asio::io_context::run() ()
#5  0x0000000000402c25 in main ()
$ pstack 40656
#0  0x00007f37c2d8f5e3 in __epoll_wait_nocancel () from /lib64/libc.so.6
#1  0x000000000040875c in boost::asio::detail::epoll_reactor::run(long, boost::asio::detail::op_queue<boost::asio::detail::scheduler_operation>&) ()
#2  0x0000000000409b84 in boost::asio::detail::scheduler::do_run_one(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&, boost::asio::detail::scheduler_thread_info&, boost::system::error_code const&) ()
#3  0x0000000000409726 in boost::asio::detail::scheduler::run(boost::system::error_code&) ()
#4  0x0000000000409f25 in boost::asio::io_context::run() ()
#5  0x0000000000402c25 in main ()
$ pstack 40656
#0  0x00007f37c2d8f5e3 in __epoll_wait_nocancel () from /lib64/libc.so.6
#1  0x000000000040875c in boost::asio::detail::epoll_reactor::run(long, boost::asio::detail::op_queue<boost::asio::detail::scheduler_operation>&) ()
#2  0x0000000000409b84 in boost::asio::detail::scheduler::do_run_one(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&, boost::asio::detail::scheduler_thread_info&, boost::system::error_code const&) ()
#3  0x0000000000409726 in boost::asio::detail::scheduler::run(boost::system::error_code&) ()
#4  0x0000000000409f25 in boost::asio::io_context::run() ()
#5  0x0000000000402c25 in main ()

PS:年纪大了,总想多唠叨唠叨,这中异步的用法,让我想起了用nodejs promise写代码函数套函数的日子,原理是一样的,nodejs用异步提供简单的http服务,总感觉有点画蛇添足,反倒是前端的各种javascript框架用起promise来很有必要,如鱼得水。
C++作为服务端用这种异步语法,就有很大的操作空间,这也难怪诸如ceph、libtorrent等这种大型项目会使用boost库。这不仅是语法的革新,也是一种编程思维的革新。打个比方,函数式编程和面向对象编程就像封建帝国,屁大点事都要写个奏折给皇上批准,批准之后才能执行。异步的编程思维就像团队运作,leader告诉每个人干完这件事之后干那件事,不用每做完一件事就去报告一次。

posted on 2021-03-31 14:47  步孤天  阅读(993)  评论(0编辑  收藏  举报