【OpenMP】互斥

既然OpenMP涉及并行编程,那么必然涉及到互斥的问题。也就是对同一个变量操作的问题。还是拿《【Java】线程并发、互斥与同步》(点击打开链接)这个抢票的程序作为例子。定义cpu的4个核都对ticket这个变量进行自减,初始为20的ticket变量去到0程序立即停止,不可以出现ticket在同一时间被减2次,导致ticket变成负数的情况。

具体程序如下:

#include <iostream>
#include <omp.h>
using namespace std;
int main()
{
	int ticket=0;//必须被初始化,不然会报错。
	int ticket_statistics[4]={0,0,0,0};
	#pragma omp parallel for num_threads(4)
	for (ticket=20;ticket>0;ticket--)
	{
		#pragma omp critical
		{
			cout<<"核cpu"<<omp_get_thread_num()<<"拿走了票,票余:"<<(ticket-1)<<endl;
			ticket_statistics[omp_get_thread_num()]++;
		}
	}
	if(ticket==0){
		cout<<"票没了,大家散了吧~得票统计:"<<endl;
		for(int i=0;i<4;i++){
			cout<<"核cpu"<<i<<"得票:"<<ticket_statistics[omp_get_thread_num()]<<"\t";
		}
		cout<<endl;
	}
	return 0;
}

首先ticket必须被初始化,尽管在for循环中给予其复制,但是不对其进行初始化依旧会报错:

OpenMP可以直接利用#pragma omp critical在其#pragma omp parallel for num_threads(线程数目)OpenMP的for循环中定义一段临界区。不用再自己去声明互斥锁之类的。其运行结果如下图所示:

虽然可以见到打印的时候没有按照20-1顺序,但可以肯定的是,ticket变量在多核cpu操作之后,依旧没有出现数据混乱的情况。最后每个cpu还相当规范地平分了这20个tickets。

值得注意的是,#pragma omp critical所定义的临界区仅能够在OpenMP的#pragma omp parallel for num_threads(线程数目)OpenMP的for循环中使用,倘若将这个程序改成while循环程序会报错的。

#include <iostream>
#include <omp.h>
using namespace std;
int main()
{
	int ticket=20;//必须被初始化,不然会报错。
	int ticket_statistics[4]={0,0,0,0};
	#pragma omp parallel num_threads(4)
	while(ticket>0)
	{
		#pragma omp critical
		{
			ticket--;
			cout<<"核cpu"<<omp_get_thread_num()<<"拿走了票,票余:"<<(ticket-1)<<endl;
			ticket_statistics[omp_get_thread_num()]++;
		}
	}
	if(ticket==0){
		cout<<"票没了,大家散了吧~得票统计:"<<endl;
		for(int i=0;i<4;i++){
			cout<<"核cpu"<<i<<"得票:"<<ticket_statistics[omp_get_thread_num()]<<"\t";
		}
		cout<<endl;
	}
	return 0;
}

运行结果如下:

也就是说,#pragma omp critical必须配合#pragma omp parallel for num_threads(线程数目)OpenMP的for循环使用

时间: 2024-10-11 10:39:01

【OpenMP】互斥的相关文章

OpenMp实现并行化

前言 昨天,往arm上移植opencv程序,发现运行速度很慢.观察资源监视器发现只有一个核处于高负荷(总共4核),遂考虑到需要多核计算.OpenMp和MPI是常用并行计算库,OpenMP相对简单适合单机多核多线程,MPI适合集群,但复杂. OpenMp是由OpenMP Architecture Review Board牵头提出的,并已被广泛接受的,用于共享内存并行系统的多处理器程序设计的一套指导性的编译处理方案(Compiler Directive).OpenMP支持的编程语言包括C语言.C++

基于GCC的openMP学习与测试

(一).openMP简述 随着CPU速度不再像以前那样显著提高,多核系统正变得越来越流行.为了利用这种能力,程序员在并行编程中变得很有知识变得越来越重要--让程序同时执行多个任务.Open Multiprocessing (OpenMP) 框架是一种功能极为强大的规范,可以帮助您利用 C.C++ 和 Fortran 应用程序中的多个核心带来的好处,是基于共享内存模式的一种并行编程模型, 使用十分方便, 只需要串行程序中加入OpenMP预处理指令, 就可以实现串行程序的并行化. 现在,openMP

Study Notes: OpenMP gramma and notes

1/ OpenMP 只是编译器的拓展,用#pragma directive(编译制导指令)来标注.如果不能并行,编译器只会忽略,并行地执行代码而不会报错.这样的作用是,可以比较方便地平行某段代码而不用大改. 2/ MIMD 和 SIMD最大的区别是,MIMD意思就是用到multi-core而SIMD则是同一个core. 3/使用OpenMP需要在GCC的compiler上加上-fopenmp且如果需要使用内置运行变量需要包含头文件 4/ OpenMP的所有编译制导指令是以#pragma omp开

OpenMp 基本

OpenMp是由OpenMP Architecture Review Board牵头提出的,并已被广泛接受的,用于共享内存并行系统的多线程程序设计的一套指导性的编译处理方案(Compiler Directive).OpenMP支持的编程语言包括C语言.C++和Fortran:而支持OpenMp的编译器包括Sun Compiler,GNU Compiler和Intel Compiler等.OpenMp提供了对并行算法的高层的抽象描述,程序员通过在源代码中加入专用的pragma来指明自己的意图,由此

openMP多线程编程

OpenMP(Open Muti-Processing) OpenMP缺点: 1:作为高层抽象,OpenMp并不适合需要复杂的线程间同步和互斥的场合: 2:另一个缺点是不能在非共享内存系统(如计算机集群)上使用.在这样的系统上,MPI使用较多. 关于openMP实现 临界区 与互斥锁 可参考 reference3 windows系统下使用 ==========================WINDOWS系统中使用========================== 基本使用: 在visual 

并行计算之OpenMP

在上一篇文章中介绍了并行计算的基础概念,也顺便介绍了OpenMP. OpenMp提供了对于并行描述的高层抽象,降低了并行编程的难度和复杂度,这样程序员可以把更多的精力投入到并行算法本身,而非其具体实现细节.对基于数据分集的多线程程序设计,OpenMP是一个很好的选择.同时,使用OpenMP也提供了更强的灵活性,可以较容易的适应不同的并行系统配置.线程粒度和负载平衡等是传统多线程程序设计中的难题,但在OpenMp中,OpenMp库从程序员手中接管了部分这两方面的工作.但是,作为高层抽象,OpenM

信号量 (线程互斥)

信号量:表示可用资源的数量,MUTEX是非0即为1的, 即,如果信号量描述的资源数目是1时,此时的信号量和互斥锁相同! 调用sem_wait()可以获得资源(P操作),使semaphore的值减1,如果调用sem_wait()时 semaphore的值已经是0,则挂起等待.如果不希望挂起等待,可以调用sem_trywait() .调用 sem_post() 可以释放资源(V操作),使semaphore 的值加1,同时唤醒挂起等待的线程. 1.生产者不会把消费者套个圈 2.消费者不会超过生产者  

秒杀多线程第十五篇 关键段,事件,互斥量,信号量的“遗弃”问题

版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 秒杀多线程第十五篇 关键段,事件,互斥量,信号量的“遗弃”问题 在<秒杀多线程第九篇 经典线程同步总结 关键段 事件 互斥量 信号量>中对经典多线程同步互斥问题进行了回顾和总结,这篇文章对Windows系统下常用的线程同步互斥机制——关键段.事件.互斥量.信号量进行了总结.有网友问到互斥量能处理“遗弃”问题,事件和信号量是否也能处理“遗弃”问题.因此本文将对事件和信号量作个试验,看看事件和信号量能否处理“遗弃”问题. 一.

OpenMp多线程编程计时问题

在做矩阵乘法并行化测试的时候,在利用<time.h>的clock()计时时出现了一点问题. 首先看串行的程序: // matrix_cpu.c #include <stdio.h> #include <stdlib.h> #include <time.h> #define NUM 2048 void matrixMul(float *A, float *B, float *C, int M, int K, int N) {     int i, j, k;