How to use boost :: thread mutex to synchronize write access?

My newbie question is about Boost::Thread and Mutex .

I would like to run many parallel instances of the following Worker , and they all write 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, eg for(std::size_t i = 0; i < vec->size(); ++i) { (*vec)[i] += some_value; } } }; 

I understand that a Worker must block vec before writing and unlocking it when it is done (because all Workers write the same vector). But how to express it?

+4
source share
2 answers

To protect the vector, you need boost :: mutex, and you can use boost :: mutex :: scoped_lock, which will lock the mutex in its constructor and unlock it in the destructor

Keep in mind that you need to use the same mutex wherever you access this vec instance, whether read or write.

For you to go, 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, eg boost::mutex::scoped_lock lock(vec_mutex); for(std::size_t i = 0; i < vec->size(); ++i) { (*vec)[i] += some_value; } } }; 

For more advanced materials, you have to encapsulate the vector and the mutex further, or sooner or later you forget that they must be connected, and you will have access to vec somewhere without holding the lock, which is very difficult to debug problems. For problems like this example, I would prefer that the workers use their own separate vectors and combine the result in the control flow when the workers are done.

+8
source

OT, but the useful information I hope for is as you update this vector a lot (or just for best practice), consider iterators for repeating vector elements. Fast execution of working code, without requiring the use of vector<double>::operator[] , will reduce the total waiting time for your workflows.

 for(std::vector<double>::iterator iter = vec->begin(); iter != vec->end(); ++iter) { *iter += some_value; } 
0
source

All Articles