Skip to content

Instantly share code, notes, and snippets.

@gcharnock
Created June 22, 2011 22:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gcharnock/1041351 to your computer and use it in GitHub Desktop.
Save gcharnock/1041351 to your computer and use it in GitHub Desktop.
Code that hangs on barrier.wait()
/*
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
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment