在多线程编程中必须考虑到不同的线程对同一个变量进行读写访问引起的数据竞争问题。如果线程间没有互斥机制,则不同线程对同一变量的访问顺序是不确定的,有可能导致错误的执行结果。

OpenMP中有两种不同类型的线程同步机制,一种是互斥机制,一种是事件同步机制。


互斥锁机制的设计思路是对一块共享的存储空间进行保护,保证任何时候最多只能有一个线程对这块存储空间进行访问,从而保证数据的完整性,这块存储空间称为“临界区”。可以通过critical、atomic等制导指令以及API中的互斥函数来实现。

事件同步机制的设计思路是控制线程的执行顺序,可以通过设置barrier同步路障、ordered定序区段、matser主线程执行等实现。

互斥锁之critical定义临界区

使用critical定义临界区的格式如下:

#pragma omp critical {需要被保护的代码块}

例如如下示例:

#include<iostream>
#include"omp.h" using namespace std; void main()
{
int sum = 0;
#pragma omp parallel for for (int i = 0; i < 10000; i++)
{
#pragma omp critical
{
sum += i;
}
}
cout << sum << endl;
system("pause");
}

加上critical之后可以保证每次执行结果总是正确的,值为49995000,但如果不加critical语句,结果可能不确定,某次执行的结果为:46932347。

互斥锁之atomic原子操作

制导指令critical可以定义一个任意大小的代码块作为临界区保护,atomic原子操作应用在单条赋值语句中。

#include<iostream>
#include"omp.h" using namespace std; void main()
{
int sum = 0;
#pragma omp parallel for for (int i = 0; i < 10000; i++)
{
{
#pragma omp atomic
sum += i;
}
}
cout << sum << endl;
system("pause");
}

事件同步之barrier(同步路障)

barrier是OpenMP中线程同步的一种方法,在多线程代码块中插入barrier,则先完成计算任务的线程到达此处会等待,直到最后一个线程也完成了计算任务。barrier相当于设置了一个线程的集合点,所有线程都到达之后才能继续往下执行。

#include<iostream>
#include"omp.h" using namespace std; int sum = 0; void Initialization()
{
for (int i = 0; i < 5; i++)
{
sum += i;
}
} void main()
{
#pragma omp parallel
{
Initialization();
#pragma omp barrier
printf("i=%d, thread_id=%d\n", sum, omp_get_thread_num());
}
system("pause");
}

输出:

如果没有添加barrier,由于不同的线程可能同时访问sum变量,存在数据竞争问题,导致输出的sum结果值不确定,其中一次输出为:

事件同步之ordered顺序制导

在循环代码中某些代码的执行需要按规定的顺序执行,比如在一个循环中,一部分的工作可以并行执行,而特定的部分需要按照串行的工作流程依次执行。

#include<iostream>
#include"omp.h" using namespace std; void main()
{
#pragma omp parallel for ordered
for (int i = 0; i < 5; i++)
{
#pragma omp ordered
printf("i=%d, thread_id=%d\n", i, omp_get_thread_num());
}
system("pause");
}

输出:

输出是按照i从小到达的次序依次执行的,如果不加ordered,其中一次输出为:

事件同步之master主线程执行

master制导指令用于指定一个代码块是交由主线程执行,这个代码块虽然位于parallel的并行域中,但是并不会被多个线程执行。

#include<iostream>
#include"omp.h" using namespace std; void main()
{
#pragma omp parallel
{
#pragma omp master
for (int i = 0; i<5; i++)
{
printf("i=%d, thread_id=%d\n", i, omp_get_thread_num());
}
} system("pause");
}

输出:

只有线程0,即主线程执行了该语句,如果不加master指令,其中一次输出为:

OpenMP中的同步和互斥的更多相关文章

  1. Java中线程同步锁和互斥锁有啥区别?看完你还是一脸懵逼?

    首先不要钻概念牛角尖,这样没意义. 也许java语法层面包装成了sycnchronized或者明确的XXXLock,但是底层都是一样的.无非就是哪种写起来方便而已. 锁就是锁而已,避免多个线程对同一个 ...

  2. 转载自~浮云比翼:Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)

    Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)   介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可 ...

  3. exec函数族,守护进程,线程同步和互斥

    2015.3.2 进程和程序有三点不同:1,存在位置不同,程序:硬盘,磁盘.进程:内存2. 程序是静态的,进程是动态的 执行./a.out -->bash->bash程序调用fork()- ...

  4. Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)

    介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可以看作是Unix进程的表亲,同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间, ...

  5. C#中的线程(中)-线程同步

    1.同步要领 下面的表格列展了.NET对协调或同步线程动作的可用的工具:                       简易阻止方法 构成 目的 Sleep 阻止给定的时间周期 Join 等待另一个线程 ...

  6. Windows下C++多线程同步与互斥简单运用

    1.  互斥量,Mutex #include <Windows.h> #include <iostream> using namespace std; DWORD WINAPI ...

  7. UNIX环境高级编程——线程同步之互斥量

    互斥量(也称为互斥锁)出自POSIX线程标准,可以用来同步同一进程中的各个线程.当然如果一个互斥量存放在多个进程共享的某个内存区中,那么还可以通过互斥量来进行进程间的同步. 互斥量,从字面上就可以知道 ...

  8. java同步和互斥【用具体程序说明】

    java同步和互斥[用具体程序说明]            所有对象都自动含有单一的锁,也就是所有对象都有且只有唯一的锁,所以当某个任务(线程)访问一个类A中含有sycnhronized的方法是,那么 ...

  9. Linux驱动之同步、互斥、阻塞的应用

    同步.互斥.阻塞的概念: 同步:在并发程序设计中,各进程对公共变量的访问必须加以制约,这种制约称为同步. 互斥机制:访问共享资源的代码区叫做临界区,这里的共享资源可能被多个线程需要,但这些共享资源又不 ...

随机推荐

  1. cocos 关于文件名称的各种坑 各种斜杠坑

    cocos 全部文件路径 的斜杠 必须 用 /  而不能够用 \ 不然编译到安卓各种坑 相对路径 第一个字符不可 带 / /*比如 res/test.png 这样的应该是标准的 /res/test.p ...

  2. IIS7配置PHP图解

    IIS6整合PHP详解:http://zhidao.zgsj.com/article/8/2011118142648.shtml PHP5.2.17 官方下载: http://windows.php. ...

  3. JAVA日志库2

    一.常用日志Jar关系 2015第30周四Java日志组件 接口:将所有日志实现适配到了一起,用统一的接口调用. 实现:目前主流的日志实现 旧日志到slf4j的适配器:如果使用了slf4j,但是只想用 ...

  4. 【z08】乌龟棋

    描述 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点 ...

  5. hdu Minimum Transport Cost(按字典序输出路径)

    http://acm.hdu.edu.cn/showproblem.php? pid=1385 求最短路.要求输出字典序最小的路径. spfa:拿一个pre[]记录前驱,不同的是在松弛的时候.要考虑和 ...

  6. SpringMvc中两个Controller类之间传递参数的方法

    使用SpringMvc框架,在访问ControllerA的时候,将A里面的参数传递到ControllerB中.适用于同一框架下两个不同Controller或者由rpc(dubbo)连接的两个工程里的C ...

  7. 使用Perl处理Excel之DMA映射

    使用Perl处理Excel之DMA映射 功能 通道处理,将各个通道的外设映射到通道上 外设ack信号处理 脚本执行情况 顶层Perl脚本(dma_parse.pl) 将上述两个功能脚本整合,便于调用 ...

  8. [CSS] Reduce Ambiguity in Class Names using a Naming Convention

    A solid naming convention makes it less likely to run into naming conflicts and helps establish a se ...

  9. CreateFeature与CreateFeatureBuffer区别

    转自原文CreateFeature与CreateFeatureBuffer区别 CreateFeature主要用于插入一条数据,CreateFeatureBuffer住哟啊用于插入多条数据,详细说明见 ...

  10. net的微服务架构

    net的微服务架构 眼下,做互联网应用,最火的架构是微服务,最热的研发管理就是DevOps, 没有之一.微服务.DevOps已经被大量应用,它们已经像传说中的那样,可以无所不能.特来电云平台,通过近两 ...