-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paththreads.hpp
94 lines (79 loc) · 2 KB
/
threads.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#ifndef THREADS_H
#define THREADS_H
#include <boost/thread.hpp>
#include <boost/thread/barrier.hpp>
#include <boost/function.hpp>
#include <vector>
template<typename T>
class Multithreader {
public:
Multithreader(bool useThreads)
: mUseThreads(useThreads),
numCPU(sysconf(_SC_NPROCESSORS_ONLN)),
_barrier(numCPU+1),
mFuncs(NULL) {
mQuiting = false;
if(!mUseThreads) {
return;
}
//Start the thread pool
for(long i = 0;i<numCPU;i++) {
//Start up each thread and move it to the thread vector
//(explicity copy operations are not allowed)
mWorkers.create_thread(WorkerThread(i,this));
}
}
~Multithreader() {
//Terminate the threads
if(!mUseThreads) {
return;
}
mQuiting = true;
_barrier.wait();
mWorkers.join_all();
}
void map(const std::vector<boost::function<T ()> >& funcs,std::vector<T>& mapTo) {
mFuncs = &funcs;
mMapTo = &mapTo;
mMapTo->resize(mFuncs->size());
if(!mUseThreads) {
//Do work
for(unsigned long i = 0;i<mFuncs->size();i++) {
mMapTo->at(i) = mFuncs->at(i)();
}
} else {
_barrier.wait();
//Theads to work here
_barrier.wait();
}
}
private:
bool mUseThreads;
bool mQuiting;
int numCPU;
boost::barrier _barrier;
const std::vector<boost::function<T ()> >* mFuncs;
std::vector<T>* mMapTo;
boost::thread_group mWorkers;
struct WorkerThread {
WorkerThread(long _id,Multithreader* _parent)
: id(_id),parent(_parent) {
}
void operator()() {
while(true) {
parent->_barrier.wait();
if(parent->mQuiting) {
break;
}
//Do work
for(unsigned long i = id;i<parent->mFuncs->size();i+=parent->numCPU) {
parent->mMapTo->at(i) = parent->mFuncs->at(i)();
}
parent->_barrier.wait();
}
}
long id;
Multithreader* parent;
};
};
#endif