boost asio

Boost.Asio defines boost::asio::io_service, a single class fro an I/O service object. Every program based on Boost.Asio uses an object of type boost::asio::io_service. This can also be a global variable.

1. boost::asio::steady_timer

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

using namespace boost::asio;

int main() {
  io_service ioservice;

  steady_timer timer{ioservice, std::chrono::seconds{3}};
  timer.async_wait([](const boost::system::error_code& ec) }{ std::cout << "3 sec\n"; });
  ioservice.run();
  return 0;
}

boost::asio::steady_timer is like an alarm clock. Instead of waiting for a blocking function to return when the alarm clock rings, your program will be notified. Because boost::asio::steady_timer just waits for a time period to expire, it would seem as though no external resource is accessed. However, in this case the external resource is the capability of the operating system to notify a program when a time period expires. This frees a program from creating a new thread just to call a blocking function.

Instead of calling a blocking function that will return when the alarm clock rings, Boost.Asio lets you start an asynchronous operation. To do this, call the function async_wait(), which expects a handler as the sole parameter. async_wait() return immediately. Instead of waitting three seconds until the alarm clock rings. the lambda function is called after three seconds. When async_wait() returns, a program can do something else.

A member function like async_wait() is called non-blocking. I/O objects usually also provide blocking member functions as alternatives. For example, you can call the blocking member function wait() on boost::asio::steady_timer. Because this member function is blocking, no handler is passed. wait() returns at a specific time of after a time period.

while async_wait() initiates an asynchronorous operation and returns immediately, run() blocks. Many operating systems support asynchronous operations only through a blocking function.

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

using namespace boost::asio;

int main() {
  io_service ioservice;

  steady_timer timer1{ioservice, std::chrono::seconds{3}};
  timer1.async_wait([](const boost::system::error_code& ec) }{ std::cout << "3 sec\n"; });

  steady_timer timer2{ioservice, std::chrono::seconds{4}};
  timer2.async_wait([](const boost::system::error_code& ec) }{ std::cout << "4 sec\n"; });

  ioservice.run();
  return 0;
}

run() is called on the only I/O service object in above example. This call passes control to the operating system functions that execute asynchronous operations. With their help, the first lambda function is called after three seconds and the second lambda function after four seconds.

It might come as a surprise that asynchronous operations require a call to the blocking function. However, this is not a problem because the program has to be prevented from exiting. If run() wouldn't block, main() would return, and the program would exit. If you don't want to wait fro run() to return, you only need to call run() in a new thread.

posted @ 2019-07-17 15:30  c++11  阅读(301)  评论(0编辑  收藏  举报