asio::io_context的事件循环

1. asio::io_context

    asio::io_context表示io的上下文,任何io都会涉及到一个io_context。

    同步io会隐式地启动一个io_context, 而异步io需要我们指定一个io_context。

    调用run()函数进入io事件循环。如果有io事件,事件完成会调用回调函数;  如果没有io事件, io_context会自动取消事件循环。

int main()
{  
    asio::io_context ioc;
    asio::ip::tcp::endpoint ep(asio::ip::address::from_string("127.0.0.1"), 6768);
    asio::ip::tcp::socket sock(ioc, ep.protocol());
    asio::ip::tcp::socket sock1(ioc, ep.protocol());

    sock.async_connect(ep, [](const std::error_code & err) {
        if (err.value() != 0) {
            std::cout << "Error: "<< err.message() << std::endl;
        }
    });
   
    sock1.async_connect(ep, [](const std::error_code & err) {
        if (err.value() != 0) {
            std::cout << "Error: "<< err.message() << std::endl;
        }
    });
    ioc.run();
   
    getchar();
    return 0;
}

    执行结果:

  

    调整语句ioc.run()的位置,置于两个async_connect()之间。

sock.async_connect(ep, [](const std::error_code & err) {
    if (err.value() != 0) {
        std::cout << "Error: "<< err.message() << std::endl;
    }
});
ioc.run();

// 这个回调函数不会执行了, 因为run的事件循环已经结束了
sock1.async_connect(ep, [](const std::error_code & err) {
    if (err.value() != 0) {
        std::cout << "Error: "<< err.message() << std::endl;
    }
});

    执行结果:

 

 2.asio::io_context::work  

   有时候, 我们希望调用run()后,即使没有io事件, 也不会退出事件循环, 而是一直等待, 当有了新的异步io调用的时候, 还可以继续使用该循环。 asio::io_context::work可以防止io_context在没有io事件的情退出。

int main()
{  
    asio::io_context ioc;
    asio::ip::tcp::endpoint ep(asio::ip::address::from_string("127.0.0.1"), 6768);
    asio::ip::tcp::socket sock(ioc, ep.protocol());
    asio::ip::tcp::socket sock1(ioc, ep.protocol());

    asio::io_context::work worker(ioc);
    std::thread t([&ioc]() {ioc.run(); });
   
    sock.async_connect(ep, [](const std::error_code & err) {
        if (err.value() != 0) {
            std::cout << "Error: " << err.message() << std::endl;
        }
    });
    
    sock1.async_connect(ep, [](const std::error_code & err) {
        if (err.value() != 0) {
            std::cout <<"Error: "<< err.message() << std::endl;
        }
    });
   
    std::cout << "Main thread will for 3 seconds...\n";  // 防止stop()执行过快
    std::this_thread::sleep_for(std::chrono::seconds(3));
    std::cout << "Main thread weak up...\n";
    ioc.stop();  // 显式停止io_context, 否则无法终止
    t.join();

    return 0;
}

  执行结果:

  

   注释掉语句asio::io_context::work worker(ioc)后。

   执行结果:

  

  即事件循环在没有IO事件的情况下, 就自动结束了。

3.总结

  在不确定io异步事件回调发生的情况下, 如果想要io_context事件循环一直进行, 就要使用io_context::work对象来执行。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值