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对象来执行。

发布了515 篇原创文章 · 获赞 135 · 访问量 30万+

猜你喜欢

转载自blog.csdn.net/liyazhen2011/article/details/103615124