zoukankan      html  css  js  c++  java
  • C++11用boost::asio做一个定时器

    示例代码如下:

    #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告诉每个人干完这件事之后干那件事,不用每做完一件事就去报告一次。

    转载请注明来源:https://www.cnblogs.com/bugutian/
  • 相关阅读:
    为什么基于TCP的应用需要心跳包(TCP keep-alive原理分析)
    「DDoS攻击」兴风作浪,教你如何有效防护!
    你还敢乱粘贴吗?
    TODO git如何去掉烦人的merge?
    Git修改已经push到远程的commit信息
    Oracle删除唯一索引失败提示ORA-01418:指定的索引不存在 ORACLE
    mybatis逆向生成代码 [ERROR] No plugin found for prefix 'mybatis-generator' in the current project and in the plugin groups
    MySQL 中 redo log、undo log、binlog 的总结
    VATT: Transformers for Multimodal Self-Supervised Learning from Raw Video, Audio and Text
    OPT: Omni-Perception Pre-Trainer for Cross-Modal Understanding and Generation
  • 原文地址:https://www.cnblogs.com/bugutian/p/14601426.html
Copyright © 2011-2022 走看看