OpenMP中的同步和互斥
在多线程编程中必须考虑到不同的线程对同一个变量进行读写访问引起的数据竞争问题。如果线程间没有互斥机制,则不同线程对同一变量的访问顺序是不确定的,有可能导致错误的执行结果。
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中的同步和互斥的更多相关文章
- Java中线程同步锁和互斥锁有啥区别?看完你还是一脸懵逼?
首先不要钻概念牛角尖,这样没意义. 也许java语法层面包装成了sycnchronized或者明确的XXXLock,但是底层都是一样的.无非就是哪种写起来方便而已. 锁就是锁而已,避免多个线程对同一个 ...
- 转载自~浮云比翼:Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)
Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥) 介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可 ...
- exec函数族,守护进程,线程同步和互斥
2015.3.2 进程和程序有三点不同:1,存在位置不同,程序:硬盘,磁盘.进程:内存2. 程序是静态的,进程是动态的 执行./a.out -->bash->bash程序调用fork()- ...
- Step by Step:Linux C多线程编程入门(基本API及多线程的同步与互斥)
介绍:什么是线程,线程的优点是什么 线程在Unix系统下,通常被称为轻量级的进程,线程虽然不是进程,但却可以看作是Unix进程的表亲,同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间, ...
- C#中的线程(中)-线程同步
1.同步要领 下面的表格列展了.NET对协调或同步线程动作的可用的工具: 简易阻止方法 构成 目的 Sleep 阻止给定的时间周期 Join 等待另一个线程 ...
- Windows下C++多线程同步与互斥简单运用
1. 互斥量,Mutex #include <Windows.h> #include <iostream> using namespace std; DWORD WINAPI ...
- UNIX环境高级编程——线程同步之互斥量
互斥量(也称为互斥锁)出自POSIX线程标准,可以用来同步同一进程中的各个线程.当然如果一个互斥量存放在多个进程共享的某个内存区中,那么还可以通过互斥量来进行进程间的同步. 互斥量,从字面上就可以知道 ...
- java同步和互斥【用具体程序说明】
java同步和互斥[用具体程序说明] 所有对象都自动含有单一的锁,也就是所有对象都有且只有唯一的锁,所以当某个任务(线程)访问一个类A中含有sycnhronized的方法是,那么 ...
- Linux驱动之同步、互斥、阻塞的应用
同步.互斥.阻塞的概念: 同步:在并发程序设计中,各进程对公共变量的访问必须加以制约,这种制约称为同步. 互斥机制:访问共享资源的代码区叫做临界区,这里的共享资源可能被多个线程需要,但这些共享资源又不 ...
随机推荐
- iOS ASIHTTPRequest
ASIHTTPRequest对CFNetwork API进行了封装,并且使用起来非常简单,用Objective-C编写,可以很好的应用在Mac OS X系统和iOS平台的应用程序中.ASIHTTPRe ...
- 关于stm32的输入输出
https://blog.csdn.net/u011556018/article/details/72629082
- AForge,Emgu.CV抓拍图像大小
原文:AForge,Emgu.CV抓拍图像大小 2017年,忙忙碌碌地过去了,象往年一样,依然没有时间上CSDN,博客园. 这一年是打工以来最辛苦的一年. 这一年用了不少自己没有接触过的东西.如人脸识 ...
- iOS将汉字转换为拼音
将汉字转换为拼音 - (NSString *)chineseToPinyin:(NSString *)chinese withSpace:(BOOL)withSpace { CFStringRef h ...
- Swift 带有动画效果的TabBarItem
额...貌似挺长时间没有总结新知识了,最近在看swift,之前swift刚出来的时候大体看了一遍,后来时间长了没看加之swift2.0做了比较大的调整,公司项目也不是用swift写的,也就没怎么看了, ...
- 【C++竞赛 F】yyy的三角形
时间限制:2s 内存限制:32MB 问题描述 yyy对三角形非常感兴趣,他有n个木棍,他正在用这些木棍组成三角形.这时xxx拿了两根木棍过来,xxx希望yyy能给他一根木棍,使得xxx可以组成一个三角 ...
- java File类的基本使用
package com.soar.file; import java.io.File; import java.io.IOException; public class Demo2_FileMetho ...
- alloc init初始化后对象依然还在父视图
self.TableView=[[UITableView alloc]init]; ........2个cell //下面但方法和addsubviews方法不一样 [self.view insertS ...
- [Angular] Create a custom pipe
For example we want to create a pipe, to tranform byte to Mb. We using it in html like: <div> ...
- Android 用SSL构建安全的Socket
SSL(安全套接层)是 Netscape公司在1994年开发的,最初用于WEB浏览器,为浏览器与服务器间的数据传递提供安全保障,提供了加密.来源认证和数据完整性的功能.现在SSL3.0得到了普遍的使用 ...