21

There is an example of using boost::asio.

  1. Why does this example use the boost::asio::io_service::work ?
  2. And why is srv.run (); not called to perform tasks in the threads?
int main()
{
    boost::asio::io_service srv;
    boost::asio::io_service::work work(srv);
    boost::thread_group thr_grp;
    thr_grp.create_thread(boost::bind(&boost::asio::io_service::run, &srv));
    thr_grp.create_thread(boost::bind(&boost::asio::io_service::run, &srv));

    srv.post(boost::bind(f1, 123));
    srv.post(boost::bind(f1, 321));
    //sync

    srv.post(boost::bind(f2, 456));
    srv.post(boost::bind(f2, 654));
    //sync

    srv.stop();
    thr_grp.join();
}

Update: What is the difference between the poll and run, when io_service is used without io_service::work?

int main()
{
    boost::asio::io_service srv;
    //boost::asio::io_service::work work(srv);
    std::vector<boost::thread> thr_grp;

    srv.post(boost::bind(f1, 123));
    srv.post(boost::bind(f1, 321));
    //sync

    srv.post(boost::bind(f2, 456));
    srv.post(boost::bind(f2, 654));
    //sync

    // What is the difference between the poll and run, when io_service without work?
    thr_grp.emplace_back(boost::bind(&boost::asio::io_service::poll, &srv));// poll or run?
    thr_grp.emplace_back(boost::bind(&boost::asio::io_service::run, &srv));// poll or run? 

    srv.stop();
    for(auto &i : thr_grp) i.join();

    int b;
    std::cin >> b;

    return 0;
}
Kijewski
  • 25,517
  • 12
  • 101
  • 143
Alex
  • 12,578
  • 15
  • 99
  • 195

1 Answers1

23

When the io_service::run method is called without a work object, it will return right away. Typically, that is not the behavior most developers are looking for. There are of course some exceptions, but most developers are looking to specify a thread to handle all of the asynchronous processing and don't want that thread to exit until told to do so. That is what your code example does.

The io_service::run method is specified as a delegate or function pointer in the create_thread methods. So, when the thread is created from the create_thread method it will call the io_service::run method and it passes the io_service object as an argument. Typically one io_service object can be used with multiple socket objects.

The stop method is usually called when shutting down the application or when communication between all clients/servers is no longer required and it is not anticipated that any new connections will need to be initiated.

Joel Bodenmann
  • 2,152
  • 2
  • 17
  • 44
Bob Bryan
  • 3,687
  • 1
  • 32
  • 45
  • Thanks! But what is the difference between the poll and run, when io_service is used without io_service::work? I added second example without work. According to the external behavior in this case they(poll and run) operate at 100% identical? – Alex Jun 18 '13 at 09:04
  • 2
    Sam Miller has a pretty good answer to the difference between poll and run in his answer to this [question](http://stackoverflow.com/questions/4705411/boostasio-io-service-run-vs-poll-or-how-do-i-integrate-boostasio-in-ma) – Bob Bryan Jun 18 '13 at 09:32
  • 1
    The `work` object is deprecated. Please check on the complete example: https://stackoverflow.com/a/56642587/3082081 – Neil Z. Shao Jun 18 '19 at 06:03