Running io_service in another thread

In the previous ASIO examples I have used the simple strategy of creating an ASIO I/O Service object; creating and initializing one or more I/O Object (in the last post, for instance, we created a bunch of deadline_timers); and finally calling run() on the I/O Service object.

This is OK for demonstrating the I/O Objects capabilities, but it is not the most commonly used strategy in a real world application, since io_service::run() is a synchronous call so, if we call it in our main thread, we get the unpleasant result of getting stuck there waiting for the I/O Service to terminate its job.

Usually we'd like to let another thread be stuck on io_service::run() and keep the main thread free to do more interesting stuff.

For instance our main thread could prompt the user for interrupting the execution. Admittedly not the most exciting task a main thread could do, but better than just sitting and waiting.

It is easy to adapt our code to this model, here is a basic schema in five steps:
// 1
boost::asio::io_service ios;

// 2 
// boost::asio::deadline_timer dt1 = boost::asio::deadline_timer(ios);
// ...

// 3
boost::thread bt(boost::bind(&boost::asio::io_service::run, &ios));

// 4
std::cout << "Press enter to terminate whenever you want!" << std::endl;
std::string request;
std::getline(std::cin, request);

// 5
ios.stop();
1. As usual, the first thing to do is creating an I/O Service object.
2. Then we set our I/O main job, for instance we could create one or more deadline_timers.
3. Here is the big change: the run() method of the ios object is called in another thread.
4. So the main thread is free to do whatever it wants. Here it just tells the user it is ready to terminate the execution.
5. When the user asks to terminate, we should ensure our I/O Service object leaves in a clean state, this is the reason for calling io_service::stop(), that takes care of cleanup the I/O Service task list before terminating.

3 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. What would be the result of calling the run() method from both of two new threads? Or likewise, calling run() from both the main thread, and an additional thread? Are there any cases where such a thing is desired? Many thanks,
    -J

    ReplyDelete
    Replies
    1. From the ASIO documentation: "Multiple threads may call the run() function to set up a pool of threads from which the io_service may execute handlers".
      So, yes J., it could make sense. Thank you for asking.

      Delete