(boost::format)io_service和io_service::work的基础使用

公司的代码看不懂,不知道io_service和io_service::work怎么用的,遂写此程序用于学习推理验证。

//注释中的Page是指:Boost程序库完全开发指南(第三版)
#include <iostream>
#include <boost/asio.hpp>
#include <boost/function.hpp>
#include <boost/format.hpp>
void handler_fun1(const boost::system::error_code& code, int n)
{
    std::stringstream ss; ss << code;
    boost::format fmt("handler_fun1  cur_th_id=%ld, code=%s, n=%d");
    fmt% GetCurrentThreadId() % ss.str() % n;
    std::cout << fmt.str() << std::endl;
}
void handler_fun2(const boost::system::error_code& code, int n)
{
    std::stringstream ss; ss << code;
    auto str = (boost::format("handler_fun2  cur_th_id=%|ld|, code=%|s|, n=%|d|") % GetCurrentThreadId() % ss.str() % n).str();//。。。。
    std::cout << str << std::endl;
}

int main1()
{// 请先阅读Page537关于io_service的"同步模式"和"异步模式"的讲解。
    std::cout << "main_thread_id=" << GetCurrentThreadId() << std::endl;
    boost::asio::io_service io;
    boost::asio::signal_set sig(io);
    //只需要add一次信号,io_service就会注册这个信号事件,然后,只要Ctrl+C触发了SIGINT,就会被io_service捕获。
    sig.add(SIGINT);
    //异步添加信号处理函数,添加一次,io_service捕获SIGINT后就会回调一次,然后就没有了,
    //如果想让io_service下一次捕获SIGINT后再次回调它,需要再次添加信号处理函数。
    sig.async_wait(handler_fun1);
    sig.async_wait(handler_fun2);
    io.run();
    //io_service里面没有信号处理函数了,run函数就结束了。
    return 0;
    //在这个程序中,主线程提供了io_service::run的上下文。也可以创建一个线程,在这个线程里执行run函数。
}

int main2()
{
    std::cout << "main_thread_id=" << GetCurrentThreadId() << std::endl;
    boost::asio::io_service io;
    boost::asio::signal_set sig(io, SIGINT);

    typedef void(handler_type)(const boost::system::error_code&, int);
    boost::function<handler_type> handler_lambda =
        [&](const boost::system::error_code& code, int n)
    {
        sig.async_wait(handler_lambda);
        sig.async_wait(handler_fun1);
        sig.async_wait(handler_fun2);
        auto str = (boost::format("handler_lambda  cur_th_id=%1%, code=%2%, n=%3%") % GetCurrentThreadId() % code%n).str();
        std::cout << str << std::endl;
    };
    //会按照添加函数的顺序回调函数
    sig.async_wait(handler_fun1);
    sig.async_wait(handler_lambda);
    sig.async_wait(handler_fun2);
    //回调函数全部执行完毕之前,又添加了新的回调函数。所以run函数没有结束,而是在等待下一次事件的触发。
    io.run();
    return 0;
}

int main3()
{
    std::cout << "main_thread_id=" << GetCurrentThreadId() << std::endl;
    boost::asio::io_service io;
    //请阅读Page540的io_service::work的描述。
    boost::asio::io_service::work wk(io);
    boost::asio::signal_set sig(io, SIGINT);
    sig.async_wait(handler_fun1);
    sig.async_wait(handler_fun2);
    io.run();
    //io_service::work不会启动一个线程,但它会启动一个"工作",让io_service不退出run函数。
    //io_service::work不会自动调用io_service的run函数,需要有代码显式的调用它。
    //在哪个线程里面启动了run函数,回调函数的线程号就是谁的。
    //本函数中,work启动的"工作"让io_service一直阻塞在run函数里。
    return 0;
}

#include <boost/thread.hpp>
int main4()
{
    //通用方法获取boost::thread::id的十进制的值。
    boost::thread::id main_th_id = boost::this_thread::get_id();
    std::stringstream ss; ss << main_th_id; std::string hex_str = ss.str();
    long main_th_id_long = strtol(hex_str.c_str(), (char**)NULL, 16);
    std::cout << "main_thread_id=" << main_th_id_long << std::endl;

    boost::thread_group th_gp;
    boost::asio::io_service io;
    boost::asio::io_service::work wk(io);
    boost::thread* new_th_ptr = th_gp.create_thread(boost::bind(&boost::asio::io_service::run, boost::ref(io)));
    boost::thread::id new_th_id = new_th_ptr->get_id();
    //重新解释内存布局的方法获取boost::thread::id的十进制的值。
    unsigned id_uint = *reinterpret_cast<unsigned int*>(&new_th_id);
    std::cout << "create a new thread, boost::thread::id=" << id_uint << std::endl;

    boost::asio::signal_set sig(io, SIGINT);

    int ctrl_c_count = 0;
    typedef void(handler_type)(const boost::system::error_code&, int);
    boost::function<handler_type> handler_lambda =
        [&](const boost::system::error_code& code, int n)
    {
        if (++ctrl_c_count <= 5)
        {
            sig.async_wait(handler_lambda);
            sig.async_wait(handler_fun1);
            sig.async_wait(handler_fun2);
        }
        else
        {// 析构io_service::work对象,停止"工作",让io_service能退出run函数。
            wk.~work();
        }
        auto str = (boost::format("handler_lambda  cur_th_id=%1%, code=%2%, n=%3%") % GetCurrentThreadId() % code%n).str();
        std::cout << str << std::endl;
    };
    sig.async_wait(handler_fun1);
    sig.async_wait(handler_lambda);
    sig.async_wait(handler_fun2);
    //等待线程组里的所有线程都退出。
    th_gp.join_all();
    return 0;
}
完。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值