GeeF
GeeF

Reputation: 717

Boost threadpool using asio: Threads randomly don't execute

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

Answers (2)

Jean Davy
Jean Davy

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

Igor R.
Igor R.

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

Related Questions