Search code examples
c++boost-asioboost-thread

io_service run within thread


Why in this simple class if i use directly io.run() the function will be invoked otherwise if demand the run to other thread the print will not be invoked?

#include <iostream>
#include <boost/thread.hpp>
#include <boost/asio.hpp>

using namespace std;

class test
{
  public:
    test()
    {
      io.post(boost::bind(&test::print, this));
      //io.run();
      t = boost::thread(boost::bind(&boost::asio::io_service::run, &io));
    }

    void print()
    {
      cout << "test..." << endl;
    }

  private:
    boost::thread t;
    boost::asio::io_service io;
};

int main()
{
  test();
  return 0;
}

Solution

  • The thread object is being destroyed before allowing the io_service to completely run. The thread destructor documentation states:

    [...] the programmer must ensure that the destructor is never executed while the thread is still joinable.

    If BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE is defined, the program would abort as the thread destructor would call std::terminate().


    If the io_service should run to completion, then consider joining the thread within Test's destructor. Here is a complete example that demonstrates synchronizing on the thread's completion:

    #include <iostream>
    #include <boost/asio.hpp>
    #include <boost/thread.hpp>
    
    class test
    {
    public:
      test()
      {
        io.post(boost::bind(&test::print, this));
        t = boost::thread(boost::bind(&boost::asio::io_service::run, &io));
      }
    
      ~test()
      {
        if (t.joinable())
          t.join();  
      }
    
      void print()
      {
        std::cout << "test..." << std::endl;
      }
    
    private:
      boost::thread t;
      boost::asio::io_service io;
    };
    
    int main()
    {
      test();
      return 0;
    }
    

    Output:

    test...