2011-12-22 94 views

回答

1

一個粗糙的方法是在OpenMP關鍵區域,在這裏你們都設置了「已設置」標誌和共享變量。當每個線程進入關鍵區域時,它會測試已設置的標誌,並且

更細粒度的方法是使用OpenMP鎖;你可以通過設置第一個線程鎖定其他線程不能,並使用它作爲你的標誌:

#include <stdio.h> 
#include <omp.h> 

void setonce_thread(omp_lock_t *l, int input, int *sharedvar) { 
    if (omp_test_lock(l)) { 
     printf("Set lock with %d\n", input); 
     *sharedvar = input; 
    } else { 
     printf("Could not set lock with %d\n", input); 
    } 
} 

void setonce_crit(int input, int *setflag, int *sharedvar) { 
#pragma omp critical 
    { 
     if ((*setflag) == 0) { 
      (*setflag)++; 
      *sharedvar = input; 
      printf("Set in crit with %d\n", input); 
     } else { 
      printf("Could not set in crit with %d\n", input); 
     } 
    } 
} 


int main() 
{ 
    omp_lock_t lck; 
    int sharedvar1, sharedvar2; 
    int setflag = 0; 
    int input = 17; 

    omp_set_nested(1); 
    omp_set_num_threads(9); 
    omp_init_lock(&lck); 
#pragma omp parallel shared(lck, sharedvar1, sharedvar2, setflag, input) default(none) num_threads(3) 
    { 
#pragma omp for 
     for (int i=0; i<3; i++) { 
#pragma omp parallel shared(lck, sharedvar1, sharedvar2, setflag, input) default(none) 
      { 
#pragma omp for 
       for (int j=0; j<3; j++) { 
        int id=omp_get_thread_num(); 
        setonce_thread(&lck, id, &sharedvar1); 
        setonce_crit(id, &setflag, &sharedvar2); 
       } 
      } 
     } 
     omp_unset_lock(&lck); 
    } 
    omp_destroy_lock(&lck); 

    printf("Shared Var 1 = %d\n", sharedvar1); 
    printf("Shared Var 2 = %d\n", sharedvar2); 
    printf("Set Flag  = %d\n", setflag); 
    return 0; 
} 
0

如果只寫入每個進程一次,而不是每個線程一次,那麼您不需要任何同步,因爲沒有任何同步。只要做好寫保護。

+0

我認爲OPs的問題是_how_安排每個進程只做一次。 – 2011-12-24 17:14:08