Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 241
Frank Avatar asked Feb 26 '23 05:02

Frank


1 Answers

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.

like image 78
nos Avatar answered Mar 01 '23 13:03

nos