0

For the following program multithreaded with openMP, what can I do to prevent other threads reading a "stuff" vector while one thread is writting to "stuff"?

    vector<int> stuff; //Global vector

    void loop() {
    #pragma omp parallel for
       for(int i=0; i < 8000; i++){
          func(i);
       }
    }

    void func(int& i) {
       vector<int> local(stuff.begin() + i, stuff.end()); //Reading and copying global vector "stuff"

       //Random function calls here

    #pragma omp critical
       stuff.assign(otherstuff.begin(), otherstuff.end()); //Writing to global vector "stuff"
    }
  • Possible duplicate of [How to use lock in openMP?](http://stackoverflow.com/questions/2396430/how-to-use-lock-in-openmp) – Zulan Apr 04 '17 at 07:52
  • Note that the referenced question has much more idiomatic OpenMP answers. – Zulan Apr 04 '17 at 08:06

1 Answers1

1

You can use mutexes to synchronize access to data shared among several threads:

#include <mutex>

std::mutex g_stuff_mutex;

vector<int> stuff; //Global vector

void loop() {
#pragma omp parallel for
   for(int i=0; i < 8000; i++){
      func(i);
   }
}

void func(int& i) {
   g_stuff_mutex.lock();
   vector<int> local(stuff.begin() + i, stuff.end()); //Reading and copying global vector "stuff"
   g_stuff_mutex.unlock();

   //Random function calls here

#pragma omp critical
   g_stuff_mutex.lock();
   stuff.assign(otherstuff.begin(), otherstuff.end()); //Writing to global vector "stuff"
   g_stuff_mutex.unlock();

}
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • I assume I no longer need '#pragma omp critical' with mutex lock? –  Apr 03 '17 at 23:45
  • No, you don't need that pragma anymore. But this solution only allows a single thread to access to `stuff` at any given time, regardless of whether it's a reader or writer. Consider using a [`std::shared_mutex`](http://en.cppreference.com/w/cpp/thread/shared_mutex) (with lock_shared() for the readers) instead of regular mutex if you need to allow multiple-readers/single-writer. – Mark Waterman Apr 04 '17 at 00:42
  • ...also, to maximize RAII goodness, use mutex ownership wrappers ([std::lock_guard](http://en.cppreference.com/w/cpp/thread/lock_guard), [std::unique_lock](http://en.cppreference.com/w/cpp/thread/unique_lock), [std::shared_lock](http://en.cppreference.com/w/cpp/thread/shared_lock), etc) instead of direct calls to mutex members. – Mark Waterman Apr 04 '17 at 00:50
  • Note that OpenMP does not officially support / interoperate with C++ threading concepts. Practically, I suppose this will work, but it is not particularly idiomatic or well-defined. – Zulan Apr 04 '17 at 08:09
  • Consider just using TBB for the whole thing. It has a parallel vector class and you won't need the OpenMP stuff. (https://www.threadingbuildingblocks.org/ ). It's free and open-source. It will certainly look much cleaner than mixing OpenMP and other types of lock! – Jim Cownie Apr 04 '17 at 10:36