Reputation: 717
I'm using a threadpool based on boost::asio::ioService
. However, threads sometimes don't execute the work posted to the ioService.
I built the following minimal example to investigate this:
#include <boost/thread.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include "threadpool.h"
int fib(int x) {
if (x == 0) return 0;
if (x == 1) return 1;
return fib(x-1)+fib(x-2);
}
void doSomething(int value)
{
std::cout << "doSomething(): " << fib(value) << std::endl;
}
void doSomethingElse(int value)
{
std::cout << "doSomethingElse(): " << value+value << std::endl;
}
int main(int argc, char** argv)
{
// create asio ioservice and threadgroup for the pool
boost::asio::io_service ioService;
boost::thread_group threadpool;
// Add worker threads to threadpool
for(int i = 0; i < 5; ++i)
{
threadpool.create_thread(
boost::bind(&boost::asio::io_service::run, &ioService));
}
// post work to the ioservice
ioService.post(boost::bind(doSomething, 40));
ioService.post(boost::bind(doSomethingElse, 3));
// run the tasks and return, if all queued work is finished
ioService.run();
// join all threads of the group
threadpool.join_all();
}
If I run this in a loop like so:
while true; do echo "--------------"; ./boost_threadpool_test; done
I will get output similar to this:
--------------
doSomething(): 102334155
doSomethingElse(): 6
--------------
--------------
--------------
--------------
doSomething(): 102334155
doSomethingElse(): 6
--------------
--------------
--------------
doSomething(): 102334155
doSomethingElse(): 6
--------------
--------------
doSomething(): 102334155
doSomethingElse(): 6
--------------
--------------
--------------
--------------
--------------
--------------
doSomething(): 102334155
doSomethingElse(): 6
--------------
So 2 or more consecutive lines show that the threads have not processed their work. I also tried my own implementation of a threadpool just using boost threadgroup to cut out the IOService, but with similar results. Is there some basic thing I'm getting wrong here?
BTW: I'm on Boost 1.46.1
Upvotes: 2
Views: 1048
Reputation: 2240
You should read, and read again, that post from Tanner Sansbury, he is an asio boss !
asio is not so complicated, but only once that this basic behavior is fully understood.
Welcome in the wonderful world of asio !
Upvotes: 1
Reputation: 15075
You call io_service::run()
, but don't give any work to the io_service
, so run()
just exits. Now you have to call io_service::reset()
before any subsequent run()
.
The fact that it works sometimes is due to the race condition: ioService.post(boost::bind(doSomething, 40))
might execute in the main thread a moment before the thread(s) in your pool get started, thus giving the io_service
some job.
Upvotes: 4