Reputation: 661
I have a newbie question about Boost::Thread
and Mutex
.
I would like to start many parallel instances of the following Worker
, and all of them write to the same std::vector
:
struct Worker {
std::vector<double>* vec;
Worker(std::vector<double>* v) : vec(v) {}
void operator() {
// do some long computation and then add results to *vec, e.g.
for(std::size_t i = 0; i < vec->size(); ++i) {
(*vec)[i] += some_value;
}
}
};
I understand that the Worker has to lock vec
before it write to it and unlock it when it's done (because all Workers write to the same vector). But how do I express that?
Upvotes: 4
Views: 4288
Reputation: 229274
You need a boost::mutex to protect the vector, and you can use a boost::mutex::scoped_lock that'll lock the mutex in its constructor, and unlock it in the destructor
Keep in mind you need to use that same mutex everywhere where you access that instance of vec
, be it reads or writes.
To get you going, you could do something like:
struct Worker {
boost::mutex &vec_mutex;
Worker(std::vector<double>* v,boost::mutex &v_mutex) : vec(v),vec_mutex(v_mutex) {}
void operator() {
// do some long computation and then add results to *vec, e.g.
boost::mutex::scoped_lock lock(vec_mutex);
for(std::size_t i = 0; i < vec->size(); ++i) {
(*vec)[i] += some_value;
}
}
};
For more advanced stuff, you should encapsulate the vector and mutex further, or sooner or later you'll forget that these needs to be connected and you'll access vec
somewhere without holding the lock leading to very hard to debug problems. For problems such as this example, I'd rather have the workers use their own individual vectors , and combine the result in the a controlling thread when the workers are done.
Upvotes: 8
Reputation: 54178
OT but useful info I hope - since you are updating this vector a lot (or just for best practice) consider iterators to iterate over the vector elements. Making the worker code faster by not requiring use of vector<double>::operator[]
will reduce the aggregate wait time of your worker threads.
for(std::vector<double>::iterator iter = vec->begin(); iter != vec->end(); ++iter) {
*iter += some_value;
}
Upvotes: 0