C
Christopher
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-
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.
log
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:osix_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 when item completes
boost::asio:laceholders::error, //
&itemNum)); // Arg 1 to pass to callback
}
// 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;
}
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-
The call stack looks very much like one we get in production code andrun() is. The first two make sense. I don't understand the latter.
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.
log
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:osix_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 when item completes
boost::asio:laceholders::error, //
&itemNum)); // Arg 1 to pass to callback
}
// 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;
}