$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-users] boost::thread and boost::asio::io_service questions
From: Christopher Pisz (cpisz_at_[hidden])
Date: 2011-06-10 16:27:49
I am trying to understand both of these items and how they are executing in 
our code, so I made a small demo to debug through. 
1) Why can't I pass boost::io_service by reference in the call, boost::thread 
workerThread(DoWork, 1, ioService); with a function signature of void DoWork
(const unsigned int threadNum, boost::asio::io_service * ioService) ? I 
changed it to a pointer and it works, but I don't know why I can't do it by 
reference.
2) If boost::thread is not copyable, how can I store a collection of "thread 
handles" or boost::thread objects like the variable workerThread? I can't use 
the std collections I would usually use... 
3) When stepping through the code, the debugger jumps between the main thread, 
the worker thread, and a call stack in the depths of boost code where one item 
points to the line where the call to ioService->run() is. The first two make 
sense. I don't understand the latter. 
The call stack looks very much like one we get in production code and is all I 
have to go on in trying to debug a problem. The challenge is trying to 
determing who created the thread and find that line in source, because the 
production code is keeps creating threads until the program crashes. 
#include <iostream> 
#include <boost/asio.hpp> 
#include <boost/bind.hpp> 
#include <boost/date_time/posix_time/posix_time.hpp> 
#include <boost/thread.hpp> 
//-------------------------------------------------------------------------Â----
/// This function is the entry point for each worker thread 
void DoWork(const unsigned int threadNum, boost::asio::io_service * ioService) 
{ 
    std::cout << "Doing work in worker thread: " << threadNum << "\n"; 
    // Perform the work 
    // Multiple threads may call io_service::run() to set up a pool
    //    of threads from which completion handlers may be invoked.
    ioService->run();
} 
//-------------------------------------------------------------------------Â----
/// This function gets called when the asynchronous operation completes 
/// Guarantee - A completion handler will only get called from the same thread 
that called boost::asio::io_service::run() 
void OnCompletion(const boost::system::error_code & e, const unsigned * 
itemNum)
{ 
    std::cout << "Completed item # " << *itemNum << " has completed. \n";
} 
//-------------------------------------------------------------------------Â----
int main() 
{ 
   boost::asio::io_service     ioService; 
   boost::asio::deadline_timer timer(ioService, boost::posix_time::seconds(5));
   const unsigned              maxItems = 5; 
   // Queue up some work 
   for(unsigned int itemNum = 0; itemNum < maxItems; ++itemNum) 
   { 
       // The work to do is an asynchronous wait 
       timer.async_wait(boost::bind(OnCompletion,         // Method to callback
                        boost::asio::placeholders::error, // 
                        &itemNum));                       // Arg 1 to pass
   }
   // Create a thread to do the work 
   boost::thread workerThread(DoWork, 1, &ioService); 
   // Do other stuff in the main thread 
   for(unsigned i = 0; i < 100; ++i) 
   { 
       std::cout << "Doing other work in main thread\n"; 
   } 
   // Done 
   return 0; 
}