2

Basically I need the Master thread to keep doing some operation based on the value of some global variables that can be edited (at some selected intervals) by a secondary thread. Something Like:

vector<int> mySharedVar;

void secondaryThreadFunction() {
   Do some operations
   And update mySharedVar if necessarily  
}

int main() {
 int count = 0;
 while(true) {
    count++;

    if (count%100) {  //> Each 100 iterations run a parallel thraed
      //> RUN secondaryThreadFunction in a separateThread
    }

    this is the main thread that based its operation on mySharedVar
 }
}

Which is the openmp command to run a single parallel thread with secondaryThreadFunction(); ?

Are there any other better way than this:

#pragma omp parallel num_threads(2)
    {
        int i = omp_get_thread_num();

        if (i == 0){
            mainThread();
        }
        if (i == 1 || omp_get_num_threads() != 2){
            secondaryThreadFunction();
        }
    }
dynamic
  • 46,985
  • 55
  • 154
  • 231
  • 1
    I suppose OpenMP sections are a little less hacky. – Mysticial Jul 18 '12 at 09:47
  • @Mysticial: hi lol, i took that sample from your answer :D http://stackoverflow.com/questions/7876156/openmp-run-two-functions-in-parallel-each-by-half-of-thread-pool anyway could you show me a sample? :D – dynamic Jul 18 '12 at 09:49
  • lol, This question seems to have a good example: http://stackoverflow.com/questions/2770911/how-does-the-sections-directive-in-openmp-distribute-work – Mysticial Jul 18 '12 at 09:52
  • Thanks a lot, that answer is pretty clear – dynamic Jul 18 '12 at 09:53
  • @Mysticial: anyway sections seems to be pretty the same thing of parallel example. Are there any other way to run a function or a class in a separate thread? Something like java `Thread.run();` ? I just need 2 very simple threads running forever where the second threads updates some global variables once 200ms (or when the master threads sends him a signal) – dynamic Jul 18 '12 at 09:58
  • Sounds like a task for an actual threading API. OpenMP is mainly for fork/join style of parallelism. So you'd basically need to wrap your entire program in a parallel region. – Mysticial Jul 18 '12 at 10:01

1 Answers1

1

Here is what I came up with:

#include <omp.h>
#include <unistd.h>
#include <vector>
#include <iostream>

std::vector<int> mySharedVar(10);

void secondaryThreadFunction() {
  mySharedVar[5]++;
}

int main() {
  int  i = 0 ;

#pragma omp parallel sections shared(mySharedVar) private(i)
  {
#pragma omp section
    //main thread
    {
      while( mySharedVar[5] < 10) {
        std::cout << "main: ";
        for(i=0; i < mySharedVar.size(); ++i){
          std::cout << mySharedVar[i] << " ";
        }
        std::cout << std::endl;
        usleep(1.e5); // wait 0.1 seconds
      }
    }
#pragma omp section
    {  
      while( mySharedVar[5] < 10) {
        secondaryThreadFunction();  
        usleep(3.e5); // wait 0.3 seconds
      }
    }
  }
}

compile and run with g++ -fopenmp test_omp_01.cc && ./a.out

output:

main: 0 0 0 0 0 1 0 0 0 0 
main: 0 0 0 0 0 1 0 0 0 0 
main: 0 0 0 0 0 1 0 0 0 0 
main: 0 0 0 0 0 2 0 0 0 0 
main: 0 0 0 0 0 2 0 0 0 0 
main: 0 0 0 0 0 2 0 0 0 0 
main: 0 0 0 0 0 3 0 0 0 0 
main: 0 0 0 0 0 3 0 0 0 0 
main: 0 0 0 0 0 3 0 0 0 0 
main: 0 0 0 0 0 4 0 0 0 0 
main: 0 0 0 0 0 4 0 0 0 0 
main: 0 0 0 0 0 4 0 0 0 0 
main: 0 0 0 0 0 5 0 0 0 0 
main: 0 0 0 0 0 5 0 0 0 0 
main: 0 0 0 0 0 5 0 0 0 0 
main: 0 0 0 0 0 6 0 0 0 0 
main: 0 0 0 0 0 6 0 0 0 0 
main: 0 0 0 0 0 6 0 0 0 0 
main: 0 0 0 0 0 7 0 0 0 0 
main: 0 0 0 0 0 7 0 0 0 0 
main: 0 0 0 0 0 7 0 0 0 0 
main: 0 0 0 0 0 8 0 0 0 0 
main: 0 0 0 0 0 8 0 0 0 0 
main: 0 0 0 0 0 8 0 0 0 0 
main: 0 0 0 0 0 9 0 0 0 0 
main: 0 0 0 0 0 9 0 0 0 0 
main: 0 0 0 0 0 9 0 0 0 0 
steffen
  • 8,572
  • 11
  • 52
  • 90
  • thanks +1! is it needed to put `shared(mySharedVar)` and `private(i)` ? – dynamic Jul 18 '12 at 22:20
  • Yes. How would the compiler otherwise know that you don't want both threads to increase `i`? – steffen Jul 19 '12 at 05:01
  • You could put `int i = 0;` inside the thread that uses it and having no need to put `private(i)` ? Regarding shared(mySharedVar) is it needed? mySharedVar is a global variables so compiler should know it's shared – dynamic Jul 19 '12 at 10:16
  • Concerning `i` you are right. Concerning the vector, not necessarily every variable which was declared outside the parallel block must be shared. What if you want to calculate a starting value for an iteration variable outside the block and then have it used independently by each thread... – steffen Jul 19 '12 at 10:52
  • steffen I have a question, consider if both threads needs to write something into mySharedVar, how can I gain a mutex to make the operation on it be atomic ? (to avoid race conditions) – dynamic Jul 20 '12 at 16:34
  • maybe a named critical section ? – dynamic Jul 20 '12 at 16:38
  • OpenMP takes care of that. That's why you declare it 'shared'. – steffen Jul 20 '12 at 16:44
  • Hm maybe for single istruction openmp knows, but If i have something like: `if (mySharedVar[5] < 2) mySharedVar[5] = 3;` while the other thread is updating that value i believe i need a crticial – dynamic Jul 20 '12 at 16:47