OpenMP(三) 线程同步

OpenMP --- 线程同步

1. 引言

    在OpenMP中,线程同步机制包括互斥锁同步机制和事件同步机制。

 

2. 互斥锁同步

    互斥锁同步的概念类似于Windows中的临界区(CriticalSection)以及Windows和Linux中的Mutex以及VxWorks中的SemTake和SemGive(初始化时信号量为满),即对某一块代码操作进行保护,以保证同时只能有一个线程执行该段代码。

 

3. atomic(原子)同步语法

    #pragma omp atomic

    x < + or * or - or * or / or & or | or << or >> >=expt

    (例如,x<<=1; or x*=2;)

    或

    #prgma omp atomic

    x++ or x-- or --x or ++x

    可以看到atomic的操作仅适用于两种情况:

    1. 自加减操作;

    2. x<上述列出的操作符>=expr;

 

4. 示例

   

view plain copy to clipboard print ?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #include <iostream>   
  2. #include <omp.h>   
  3.   
  4. int main()  
  5. {  
  6.    int sum = 0;  
  7.    std::cout << "Before: " << sum << std::endl;  
  8.   
  9. #pragma omp parallel for   
  10.    for(int i = 0; i < 2000; ++i)  
  11.    {  
  12.    #pragma omp atomic   
  13.       sum++;  
  14.    }  
  15.   
  16.    std::cout << "After: " << sum << std::endl;  
  17.    return 0;  
  18. }  
#include <iostream> #include <omp.h> int main() { int sum = 0; std::cout << "Before: " << sum << std::endl; #pragma omp parallel for for(int i = 0; i < 2000; ++i) { #pragma omp atomic sum++; } std::cout << "After: " << sum << std::endl; return 0; }

 

输出2000,如果将#pragma omp atomic声明去掉,则结果不确定。

 

 

5. critical同步机制

    本节介绍互斥锁机制的使用方法,类似于windows下的CriticalSection。

 

5.1 临界区声明方法

     #pragma omp critical [(name)] //[]表示名字可选

     {

           //并行程序块,同时只能有一个线程能访问该并行程序块

     }

 

     例如,

    #pragma omp critial (tst)

    a = b + c;

 

5.2 critical与atomic的区别

     临界区critical可以对某个并行程度块进行保护,atomic所能保护的仅为一句代码。

 

5.3 critical示例

      

view plain copy to clipboard print ?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. #include <iostream>   
  2. #include <omp.h>   
  3.   
  4. int main()  
  5. {  
  6.    int sum = 0;  
  7.    std::cout << "Before: " << sum << std::endl;  
  8.   
  9. #pragma omp parallel for   
  10.    for(int i = 0; i < 10; ++i)  
  11.    {  
  12.    #pragma omp critial (a)   
  13.       {  
  14.        sum = sum + i;  
  15.        sum = sum + i*2;  
  16.       }  
  17.    }  
  18.    std::cout << "After: " << sum << std::endl;  
  19.    return 0;  
  20. }  
  21.   
  22.      
#include <iostream> #include <omp.h> int main() { int sum = 0; std::cout << "Before: " << sum << std::endl; #pragma omp parallel for for(int i = 0; i < 10; ++i) { #pragma omp critial (a) { sum = sum + i; sum = sum + i*2; } } std::cout << "After: " << sum << std::endl; return 0; }   http://www.cnblogs.com/BIGFOOT/archive/2011/09/01/2162222.html

你可能感兴趣的:(OpenMP(三) 线程同步)