
I've just tried the same program with a fresh compile of boost 1.46.1 and got the same hanging problem. On Thu, Jun 23, 2011 at 10:32 AM, Gareth <gareth.tpc@gmail.com> wrote:
I'm having problems with boost::barrier. I've written a class that creates a thread pool to map evaluate an array of functions to an array of results. I've used barriers in the synchronisation. The problem is that the threads are all getting stuck at the barrier::wait calls. I've verified with gdb that all the worker threads and the manager thread are sitting in barrier::wait() however, there all stuck. I have no idea what's causing this. I've put the source code in the following github gist and also pasted it to the end of the email.
https://gist.github.com/1041351
I've also checked the bugs list for any known bugs, fixed or otherwise, to do with threading and I haven't found anything. I'm not sure what I'm doing wrong.
-Gareth Charnock
/* compile: g++ thread_template.cpp -lboost_thread
Outputs:
BOOST_VERSION = 104200 Starting thread 0 Starting thread 1 Thread 0 waiting for work Thread 1 waiting for work Threads have work... */
#include <boost/version.hpp> #include <boost/thread.hpp> #include <boost/thread/barrier.hpp> #include <boost/function.hpp> #include <iostream> #include <vector>
template<typename T> class Multithreader { public: Multithreader() : numCPU(sysconf(_SC_NPROCESSORS_ONLN)), _barrier(numCPU+1), mFuncs(NULL), mMapTo(NULL) { std::cout << "BOOST_VERSION = " << BOOST_VERSION << std::endl; //Start the thread pool for(long i = 0;i<numCPU;i++) { std::cout << "Starting thread "<<i<< std::endl; boost::thread(WorkerThread(i,this)); } }
~Multithreader() { //Terminate the threads
//todo }
void map(const std::vector<boost::function<T ()> >& funcs,std::vector<T>& mapTo) { mFuncs = &funcs; mMapTo = &mapTo;
std::cout << "Threads have work..." << std::endl; _barrier.wait(); //Workers are working at this point std::cout << "Threads are working..." << std::endl; _barrier.wait(); std::cout << "Threads have finished" << std::endl; } private: const std::vector<boost::function<T ()> >* mFuncs; std::vector<T>* mMapTo; boost::barrier _barrier;
size_t numCPU;
class WorkerThread { public: WorkerThread(long _id,Multithreader* _parent) : id(_id),parent(_parent) { } void operator()() { while(true) { std::cout << "Thread "<<id<<" waiting for work" << std::endl; parent->_barrier.wait(); std::cout << "Thread "<<id<<" has work" << std::endl; //Do work for(long i = id;i<parent->mFuncs->size();i+=parent->numCPU) { parent->mMapTo->at(i) = parent->mFuncs->at(i)(); } parent->_barrier.wait(); std::cout << "Thread "<<id<<" finished the work" << std::endl; } } long id; Multithreader* parent; };
};
#include <boost/bind.hpp>
double f(double x) { return x*2; }
int main() { //Start the thread pool Multithreader<double> mt;
std::vector<boost::function<double()> > work;work.resize(20); std::vector<double> results;results.resize(20);
//Prepare the work for(unsigned long i = 0;i<20;i++) { work[i] = boost::bind(f,i); } //Execute in parallel mt.map(work,results);
while(true) { //For the purposes of the example, keep the main thread alive //so we don't delete mt } }