C++ 多线程之OpenMP并行编程使用详解

这篇具有很好参考价值的文章主要介绍了C++ 多线程之OpenMP并行编程使用详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C++ 多线程之OpenMP并行编程使用详解

  • 总结OpenMP使用详解
  • 本文转载自:https://blog.csdn.net/AAAA202012/article/details/123665617?spm=1001.2014.3001.5506

1.总览

  OpenMP(Open Multi-Processing)是一种用于共享内存并行系统的多线程程序设计方案,支持的编程语言包括C、C++和Fortran。OpenMP提供了对并行算法的高层抽象描述,通过线程实现并行化,特别适合在多核CPU机器上的并行程序设计。编译器根据程序中添加的pragma指令,自动将程序并行处理,使用OpenMP降低了并行编程的难度和复杂度。当编译器不支持OpenMP时,程序会退化成普通(串行)程序。程序中已有的OpenMP指令不会影响程序的正常编译运行。

OpenMP与Pthread有着许多本质不同:

  • Pthread需要显式地明确每个线程的行为; OpenMP只需要简单的声明这块代码并行执行。
  • 只要系统拥有Pthreads库,Pthreads程序就能够被任意的C编译器使用;除了拥有OpenMP还要求编译器支持某些操作。
  • Pthreads提供了虚拟地编写任何可知线程行为的能力;OpenMP用于实现并行更加简单,但是很难对底层的线程交互进行编程。

OpenMP采用fork-join的执行模式。开始的时候只存在一个主线程,当需要进行并行计算的时候,派生出若干个分支线程来执行并行任务。当并行代码执行完成之后,分支线程会合,并把控制流程交给单独的主线程。

Fork(派生):主线程(master thread)创建一组并行化执行的线程;
Join(合并):当线程完成工作后,它们会进行同步与终止,只剩下master thread。
C++ 多线程之OpenMP并行编程使用详解,C++特性,c++,开发语言,windows,visual studio,多线程

2.编译

使用gcc编译OpenMP程序,需要在后面包含-fopenmp选项;

在VS中启用OpenMP,在项目上右键 -> 属性 -> 配置属性 ->C/C++ -> 语言 -> OpenMP支持,选择“是”即可。

3.编译制导指令

编译制导指令以#pragma omp开始,后面根具体的功能指令,格式如:#pragma omp 指令[子句,[子句]…]。常用的功能指令如下:

  • parallel:用在一个结构块之前,表示这段代码将被多个线程并行执行;
  • for:用于for循环语句之前,表示将循环计算任务分配到多个线程中并行执行,以实现任务分担,必须由编程人员自己保证每次循环之间无数据相关性;
  • parallel for: parallel和for指令的结合,也是用在for循环语句之前,表示for循环体的代码将被多个线程并行执行,它同时具有并行域的产生和任务分担两个功能;
  • sections:用在可被并行执行的代码段之前,用于实现多个结构块语句的任务分担,可并行执行的代码段各自用section指令标出(注意区分sections和section);
  • parallel sections:parallel和sections两个语句的结合,类似于parallel for;
  • single:用在并行域内,表示一段只被单个线程执行的代码;
  • critical:用在一段代码临界区之前,保证每次只有一个OpenMP线程进入;
  • flush:保证各个OpenMP线程的数据影像的一致性;
  • barrier:用于并行域内代码的线程同步,线程执行到barrier时要停下等待,直到所有线程都执行到barrier时才继续往下执行;
  • atomic:用于指定一个数据操作需要原子性地完成;
  • master:用于指定一段代码由主线程执行;
  • threadprivate:用于指定一个或多个变量是线程专用;

相应的OpenMP子句为:

  • private:指定一个或多个变量在每个线程中都有它自己的私有副本;
  • firstprivate:指定一个或多个变量在每个线程都有它自己的私有副本,并且私有变量要在进入并行域或任务分担域时,继承主线程中的同名变量的值作为初值;
  • lastprivate:是用来指定将线程中的一个或多个私有变量的值在并行处理结束后复制到主线程中的同名变量中,负责拷贝的线程是for或sections任务分担中的最后一个线程;
  • reduction:用来指定一个或多个变量是私有的,并且在并行处理结束后这些变量要执行指定的归约运算,并将结果返回给主线程同名变量;
  • nowait:指出并发线程可以忽略其他制导指令暗含的路障同步;
  • num_threads:指定并行域内的线程的数目;
  • schedule:指定for任务分担中的任务分配调度类型;
  • shared:指定一个或多个变量为多个线程间的共享变量;
  • ordered:用来指定for任务分担域内指定代码段需要按照串行循环次序执行;
  • copyprivate:配合single指令,将指定线程的专有变量广播到并行域内其他线程的同名变量中;
  • copyin:用来指定一个threadprivate类型的变量需要用主线程同名变量进行初始化;
  • default:用来指定并行域内的变量的使用方式,缺省是shared。

>OpenMP parallel

parallel制导指令用来创建并行域,后边要跟一个大括号将要并行执行的代码放在一起

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

void hello(void) {
    //返回线程号
	int my_rank = omp_get_thread_num();
    //返回当前并行区域中的线程数
	int thread_count = omp_get_num_threads();
	printf("Hello from thread %d of %d. \n", my_rank, thread_count);
}

int main(int argc, char** argv) {
	int thread_count = strtol(argv[1],NULL,10);
	
//num_threads指定要用多少个线程来实现hello
#pragma omp parallel num_threads(thread_count)
{
	hello();
}
	return 0;
}

C++ 多线程之OpenMP并行编程使用详解,C++特性,c++,开发语言,windows,visual studio,多线程

>OpenMP for

#pragma omp parallel for它告诉编译器,接下来的for循环,将会使用并行的方式执行,使用并行的时候需要满足以下四个需求:

  • 在循环的迭代器必须是可计算的并且在执行前就需要确定迭代的次数;
  • 在循环的代码块中不能包含break,return,exit;
  • 在循环的代码块中不能使用goto跳出到循环外部;
  • 迭代器只能够被for语句中的增量表达式所修改。

数据依赖性:在该循环中的计算依赖于一个或更多个先前的迭代结果。当存在这种状况时,需要格外注意,容易出现错误。

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

int main(int argc, char** argv) {
	int thread_count = strtol(argv[1],NULL,10);
	double a[10], b[10];
	for (int i = 0; i < 10; i++) {
		a[i] = i;
		b[i] = 10 - i;
	}
	double s[10];
#pragma omp parallel for num_threads(thread_count)
	for (int i = 0; i < 10; i++){
		s[i] = a[i] + b[i];
		printf("线程编号%d: 结果%lf\n",omp_get_thread_num(), s[i]);
	}

	return 0;
}

C++ 多线程之OpenMP并行编程使用详解,C++特性,c++,开发语言,windows,visual studio,多线程

>OpenMP private Variables

在OpenMP中,变量的作用域涉及在parallel块中能够访问该变量的线程集合。能够被线程组中所有线程访问的变量拥有共享作用域,而一个只能被单个线程访问的变量拥有私有作用域。

Private在#pragma中作为一个可选的,附加的选项,它能够直接的告诉编译器去使得共享变量作为每个线程中的私有变量。它的形式为 #pragma omp … private(< variable list >)

>>>private

关于private的信息:

  • 每一个线程都是拥有独自的该变量的副本;
  • 如果j被定义为私有变量,那么在for循环里面,所有的线程都不能访问其他j(尽管j是共享变量);
  • 所有的线程都不会使用到先前的定义;
  • 所有线程都不能给共享的j赋值;
#include<stdio.h>
#include<stdlib.h>
#include<omp.h>

int main(int argc, char** argv) {
	int thread_count = strtol(argv[1],NULL,10);
	double tmp = 1.0f;
#pragma omp parallel for num_threads(thread_count) private(tmp) 
	for (int i = 0; i < 10; i++)
	{
		tmp = 2.0f;
		printf("线程编号%d: 结果%lf\n", omp_get_thread_num(), tmp);
	}

	printf("tmp: %lf\n",tmp);

	return 0;
}

C++ 多线程之OpenMP并行编程使用详解,C++特性,c++,开发语言,windows,visual studio,多线程

>>>firstprivate

关于firstprivate的信息:

  • firstprivate选项告诉编辑器私有变量在第一个循环会继承共享变量的值;
  • 这个私有的变量只会在每个线程的第一个循环继承,而不会在每个循环中继承;
  • 其使用方法于private几乎一致:#pragma omp parallel for firstprivate;

关于变量的拷贝:

  • 如果数据是基础数据类型,如int,double等,会将数据进行直接拷贝;
  • 如果变量是一个数组,它会拷贝一个对应的数据以及大小到私有内存中;
  • 如果变量为指针,它会将变量指向的地址拷贝过去,指向相同地址;
  • 如果变量是一个类的实例,它会调用对应的构造函数构造一个私有的变量。
#include<stdio.h>
#include<stdlib.h>
#include<omp.h>

int main(int argc, char** argv) {
	int thread_count = strtol(argv[1],NULL,10);
	int j = 4;
#pragma omp parallel for num_threads(thread_count) firstprivate(j) 
	for (int i = 0; i < 10; i++)
	{
		j++;
		int my_rank = omp_get_thread_num();
		int thread_count = omp_get_num_threads();
		printf("thread %d of %d has j = %d.\n", my_rank,thread_count,j);
	}

	printf("tmp: %d\n",j);

	return 0;
}

C++ 多线程之OpenMP并行编程使用详解,C++特性,c++,开发语言,windows,visual studio,多线程

>>>lastprivate

关于lastprivate的信息:

  • lastprivate选项告诉编辑器私有变量会在最后一个循环出去的时候,用私有变量的值替换掉我们共享变量的值;
  • 当负责最后一个iteration的线程离开循环的时候,它会将该私有变量的值赋值给当前共享变量的值。
#include<stdio.h>
#include<stdlib.h>
#include<omp.h>

int main(int argc, char** argv) {
	int thread_count = strtol(argv[1],NULL,10);
	int j;
#pragma omp parallel for num_threads(thread_count) lastprivate(j) 
	for (int i = 0; i < 10; i++)
	{
		j = 4;
		j++;
		int my_rank = omp_get_thread_num();
		int thread_count = omp_get_num_threads();
		printf("thread %d of %d has j = %d.\n", my_rank,thread_count,j);
	}

	printf("tmp: %d\n",j);

	return 0;
}

C++ 多线程之OpenMP并行编程使用详解,C++特性,c++,开发语言,windows,visual studio,多线程

>OpenMP section

sections在封闭代码的指定部分中,由线程组进行分配任务:

  • 每个独立的section都需要在sections里面;
  • 每个section可能执行不同的任务;
  • 如果一个线程够快,该线程可能执行多个section。
#include<stdio.h>
#include<stdlib.h>
#include<omp.h>

int main(int argc, char** argv) {
	int thread_count = strtol(argv[1],NULL,10);
#   pragma omp parallel num_threads(thread_count)
	{
#       pragma omp sections
	   {
#          pragma omp section
	       {
			   int my_rank = omp_get_thread_num();
			   int thread_count = omp_get_num_threads();
			   printf("thread %d of %d.\n", my_rank, thread_count);
	       }
#          pragma omp section
		   {
			   int my_rank = omp_get_thread_num();
			   int thread_count = omp_get_num_threads();
			   printf("thread %d of %d.\n", my_rank, thread_count);
		   }
#		   pragma omp section
		   {
			   int my_rank = omp_get_thread_num();
		   int thread_count = omp_get_num_threads();
		   printf("thread %d of %d.\n", my_rank, thread_count);
		   }
#		   pragma omp section
		   {
			   int my_rank = omp_get_thread_num();
		   int thread_count = omp_get_num_threads();
		   printf("thread %d of %d.\n", my_rank, thread_count);
		   }
	   }
	}
	return 0;
}

C++ 多线程之OpenMP并行编程使用详解,C++特性,c++,开发语言,windows,visual studio,多线程

>>>reduction

reduction也是一种常见的子句,它为我们的parallel,for和sections提供了一个归并的功能:

  • 它会提供一个私有的变量拷贝并且初始化该私有变量;
  • 私有变量的初始化的值取决于选择的归并的操作符;
  • 这些变量的拷贝会在本地线程中进行更新;
  • 在最后的出口中,所有的变量拷贝将会通过操作符所定义的规则进行合并的计算,计算成一个共享变量;
  • 使用方法如下:#pragma omp … reduction(op:list)。

reduction提供的操作符几乎都是符合结合律的二元操作符,本地变量的初始值如下所示:

Operator Initial Value
+ 0
* 1
- 0
^ 0
& ~0
0
&& 1
丨丨 0
#include<stdio.h>
#include<stdlib.h>
#include<omp.h>

int main(int argc, char** argv) {
	int thread_count = strtol(argv[1],NULL,10);
	int j = 10;
	printf("j = %d\n", j);
#   pragma omp parallel num_threads(thread_count) reduction(+:j)
	{
#       pragma omp sections
	   {
#          pragma omp section
	       {
			   int my_rank = omp_get_thread_num();
			   int thread_count = omp_get_num_threads();
			   j = j + 10;
			   printf("Hello from thread %d of %d in section 1 and j = %d.\n", my_rank, thread_count,j);
	       }
#          pragma omp section
		   {
			   int my_rank = omp_get_thread_num();
			   int thread_count = omp_get_num_threads();
			   j = j + 20;
			   printf("Hello from thread %d of %d in section 2 and j = %d.\n", my_rank, thread_count, j);
		   }
	   }
	}

	printf("j = %d\n",j);
	return 0;
}

C++ 多线程之OpenMP并行编程使用详解,C++特性,c++,开发语言,windows,visual studio,多线程

>OpenMP single

single选项是在并行块里面使用的:

  • 它告诉编译器接下来紧跟的下段代码将会只一个线程执行;
  • 它可能会在处理多段线程不安全代码时非常有用;
  • 在不使用no wait选项时,在线程组中不执行single的线程们将会等待single的结束
#pragma omp single nowait
{
   nthreads = omp_get_num_threads();
   printf("number of threads = %d\n",nthreads);
}

//与上面的代码大致等同
tid = omp_get_thread_num();
if(tid == 0){
   nthreads = omp_get_num_threads();
   printf("number of threads = %d\n",nthreads);
}

>OpenMP master

master选项是在并行块里面使用的:

  • 它告诉编译器接下来紧跟的下段代码将会会由主线程执行;
  • 它不会出现等待现象。
#pragma omp master
{
   nthreads = omp_get_num_threads();
   printf("number of threads = %d\n",nthreads);
}

//与上面的代码等同
tid = omp_get_thread_num();
if(tid == 0){
   nthreads = omp_get_num_threads();
   printf("number of threads = %d\n",nthreads);
}

>OpenMP barrier

在很多时候,需要线程之间团结协作完成某个任务,这就要求线程能够完成一致协调合作。OpenMP提供了多个操作,其中barrier和critical分别用于实现同步与互斥。

它是用于实现同步的一种手段,会在代码的某个点,令线程停下直到所有的线程都到达该地方。使用的语法如下:#pragma omp barrier。许多情况下,它已经能够自动的插入到工作区结尾,比如在for,single中,但是它能够被nowait禁用。

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

int main(int argc, char** argv) {
	int thread_count = strtol(argv[1],NULL,10);
	printf("使用barrier输出的结果:\n");
#   pragma omp parallel num_threads(thread_count)
	{
		int my_rank = omp_get_thread_num();
		int thread_count = omp_get_num_threads();
		printf("hi from %d\n", my_rank);
#       pragma omp barrier
		if (my_rank == 0) {
			printf("%d threads say hi\n", thread_count);
		}
	}
	printf("不使用barrier输出的结果:\n");
#   pragma omp parallel num_threads(thread_count)
	{
		int my_rank = omp_get_thread_num();
		int thread_count = omp_get_num_threads();
		printf("hi from %d\n", my_rank);
//#       pragma omp barrier
		if (my_rank == 0) {
			printf("%d threads say hi\n", thread_count);
		}
	}
	return 0;
}

C++ 多线程之OpenMP并行编程使用详解,C++特性,c++,开发语言,windows,visual studio,多线程

>>>nowait

nowait在OpenMP中,用于打断自动添加的barrier的类型,如parallel中的for以及single,用法如下:#pragma omp for nowait 、#pragma omp single nowait。

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

int main(int argc, char** argv) {
	int thread_count = strtol(argv[1],NULL,10);
	printf("使用nowait输出的结果:\n");
#   pragma omp parallel num_threads(thread_count)
	{
		int my_rank = omp_get_thread_num();
		int thread_count = omp_get_num_threads();
#       pragma omp for nowait
		for (int i = 0; i < 10; i++) {
			if (my_rank == 0)
				Sleep(3000);
			printf("Hello from thread %d of %d i = %d.\n", my_rank, thread_count, i);
		}
#       pragma omp single nowait
		{
			printf("thread %d process single\n", my_rank);
			Sleep(3000);
		}
		printf("thread %d ok\n", my_rank);
	}

	printf("不使用nowait输出的结果:\n");
#   pragma omp parallel num_threads(thread_count)
	{
		int my_rank = omp_get_thread_num();
		int thread_count = omp_get_num_threads();
#       pragma omp for
		for (int i = 0; i < 10; i++) {
			if (my_rank == 0)
				Sleep(3000);
			printf("Hello from thread %d of %d i = %d.\n", my_rank, thread_count, i);
		}
#       pragma omp single
			printf("thread %d process single\n", my_rank);
			Sleep(3000);
		printf("thread %d ok\n", my_rank);
	}
	return 0;
}

C++ 多线程之OpenMP并行编程使用详解,C++特性,c++,开发语言,windows,visual studio,多线程

>OpenMP critical

竞争现象可以由下图表示:

C++ 多线程之OpenMP并行编程使用详解,C++特性,c++,开发语言,windows,visual studio,多线程
OpenMP提供了一个实现互斥的接口:critical,它告诉编译器解析来的一段代码在同一个时间段将会只由一个线程进行,使用方法如下:#pragma omp critical。好处是解决了竞争现象;坏处是使用critical会让程序执行减少并行化程序,而且必须要写代码的人手动判断哪些部分需要用critical。

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

int main(int argc, char** argv) {
	int thread_count = strtol(argv[1],NULL,10);
	int j = 0;
#   pragma omp parallel for num_threads(thread_count) shared(j)
		for (int i = 0; i < 10; i++) {
			int my_rank = omp_get_thread_num();
			int thread_count = omp_get_num_threads();
#           pragma omp critical
			{
				j = j + 1;
				printf("Hello from thread %d of %d i = %d,j = %d\n", my_rank, thread_count, i, j);
			}
		}
	return 0;
}

C++ 多线程之OpenMP并行编程使用详解,C++特性,c++,开发语言,windows,visual studio,多线程

>OpenMP atomic

在特殊的情况下,除了使用critical指令控制临界区以外,我们还可以使用其他选项去保证内存的控制是原子的,OpenMP提供了一个选项:atomic(原子),它只在特殊的情况下使用:在自增或自减的情况下使用;在二元操作数的情况下使用。并且其只会应用于一条指令。使用方法如下:#pragma omp atomic。

critical与atomic的区别如下图所示:
C++ 多线程之OpenMP并行编程使用详解,C++特性,c++,开发语言,windows,visual studio,多线程

>OpenMP schedule

循环调度的种类:

  • 静态调度:在循环执行之前,就已经将循环任务分配好;
  • 动态调度:在循环执行过程中,边执行边分配。

OpenMP提供了一个指令schedule,它能够将循环分配给每个线程,当采用不同的参数时,我们会使用不同的调度方式。它的使用方式如下:shedule(static[,chunk]),当采用static的参数时,chunk代表了每一块分块的大小,它会采取转轮制度,谁先获取块,谁就能获得整一块的内容。特点是低开销,但是可能会造成分配的不均衡。具体理解如下图所示:

C++ 多线程之OpenMP并行编程使用详解,C++特性,c++,开发语言,windows,visual studio,多线程

它的使用方式还有:shedule(dynamic[,chunk]),当采用dynamic的参数时,chunk代表了每一块分块的大小,每个线程执行完毕后,会自动获取下一个块,特点是高开销,但是能减少分配不均衡的情况。具体分配方式如下图所示:

C++ 多线程之OpenMP并行编程使用详解,C++特性,c++,开发语言,windows,visual studio,多线程

它的使用方式还有:shedule(guide[,chunk]),当采用guide的参数时,会按照一定的规则分配块,这是一种动态的分配,每一块的分配数量是在不断收缩的,但是最小不会小于chunk。最初的块会被定义成:循环数量/线程数。其余块的大小会被定义成:剩余循环数量/线程数。具体分配方式如下图所示:

C++ 多线程之OpenMP并行编程使用详解,C++特性,c++,开发语言,windows,visual studio,多线程

#include<omp.h>
#include<windows.h>
#include<time.h>

void delay() {
	int t = 50;
	int my_rank = omp_get_thread_num();
	t = t * (my_rank + 1);
	Sleep(t);
}

int main(int argc, char** argv) {
	int thread_count = strtol(argv[1],NULL,10);
	int j = 0;
	srand(time(NULL));
	clock_t start, end;
	start = clock();
#   pragma omp parallel for num_threads(thread_count) schedule(static,2)
		for (int i = 0; i < 100; i++) {
			delay();
		}
	end = clock();
	printf("first loop finish,time: %f\n", (double)end - start);

	start = clock();
#   pragma omp parallel for num_threads(thread_count) schedule(dynamic,2)
	for (int i = 0; i < 100; i++) {
		delay();
	}
	end = clock();
	printf("second loop finish,time: %f\n", (double)end - start);

	start = clock();
#   pragma omp parallel for num_threads(thread_count) schedule(guided,2)
	for (int i = 0; i < 100; i++) {
		delay();
	}
	end = clock();
	printf("third loop finish,time: %f\n", (double)end - start);
	return 0;
}

4.环境变量

OpenMP中定义一些环境变量,可以通过这些环境变量控制OpenMP程序的行为,常用的环境变量如下:文章来源地址https://www.toymoban.com/news/detail-737263.html

  • OMP_SCHEDULE:用于for循环并行化后的调度,它的值就是循环调度的类型;
  • OMP_NUM_THREADS:用于设置并行域中的线程数;
  • OMP_DYNAMIC:通过设定变量值,来确定是否允许动态设定并行域内的线程数;
  • OMP_NESTED:指出是否可以并行嵌套。

5.API函数

函数名 函数作用
omp_in_parallel 判断当前是否在并行域中
omp_get_thread_num 返回线程号
omp_set_num_threads 设置后续并行域中的线程格式
omp_get_num_threads 返回当前并行区域中的线程数
omp_get_max_threads 获取并行域可用的最大线程数目
omp_get_num_procs 返回系统中处理器的个数
omp_get_dynamic 判断是否支持动态改变线程数目
omp_set_dynamic 启用或关闭线程数目的动态改变
omp_get_nested 判断系统是否支持并行嵌套
omp_set_nested 启用或关闭并行嵌套

到了这里,关于C++ 多线程之OpenMP并行编程使用详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++开发基础之网络编程WinSock库使用详解TCP/UDP Socket开发

    Winsock是Windows操作系统提供的用于网络编程的API库。它是Windows Sockets的简称,也就是套接字库。Winsock可以让开发人员使用TCP/IP协议族中的各种协议,如TCP、UDP等,在Windows平台下进行网络编程。 Winsock提供了一组函数和数据结构,这些函数和数据结构可以让开发人员创建和管理

    2024年01月23日
    浏览(50)
  • C++多线程编程(第三章 案例1,使用互斥锁+ list模拟线程通信)

    主线程和子线程进行list通信,要用到互斥锁,避免同时操作 1、封装线程基类XThread控制线程启动和停止; 2、模拟消息服务器线程,接收字符串消息,并模拟处理; 3、通过Unique_lock和mutex互斥方位list 消息队列 4、主线程定时发送消息给子线程; 代码包含了XThread类(基类)、

    2024年02月15日
    浏览(35)
  • 【C++】多线程(thread)使用详解

    多线程(multithreading),是指在软件或者硬件上实现多个线程并发执行的技术。具有多核CPU的支持的计算机能够真正在同一时间执行多个程序片段,进而提升程序的处理性能。在一个程序中,这些独立运行的程序片段被称为“ 线程 ”(Thread),利用其编程的概念就叫作“多线

    2024年02月14日
    浏览(41)
  • C++并发线程 - 如何线程间共享数据【详解:如何使用锁操作】

    点击进入系列文章目录 C++技能系列 Linux通信架构系列 C++高性能优化编程系列 深入理解软件架构设计系列 高级C++并发线程编程 期待你的关注哦!!! 快乐在于态度,成功在于细节,命运在于习惯。 Happiness lies in the attitude, success lies in details, fate is a habit. 具体哪个线程按何种

    2024年02月08日
    浏览(39)
  • Java并发(二)----初次使用多线程并行提高效率

    并行代表充分利用多核 cpu 的优势,提高运行效率。 想象下面的场景,执行 3 个计算,最后将计算结果汇总。 如果是串行执行,那么总共花费的时间是 10 + 11 + 9 + 1 = 31ms 但如果是四核 cpu,各个核心分别使用线程 1 执行计算 1,线程 2 执行计算 2,线程 3 执行计算 3,那么 3 个

    2023年04月13日
    浏览(67)
  • 【C++】OpenMP简介

    1、program作用 #pragma 是 C 和 C++ 语言中的一个预处理指令。它主要用于向编译器发送特定的信息或者指示,以便控制编译过程。#pragma 通常与编译器特定的选项或功能一起使用,因此它的具体行为和实现可能因不同的编译器而有所不同。 #pragma 的语法如下: 其中,directive_name

    2024年02月05日
    浏览(30)
  • 【C#】并行编程实战:使用 PLINQ(2)

             PLINQ 是语言集成查询(Language Integrate  Query  ,  LINQ )的 并行 实现(P 表示并行)。本章将继续介绍其编程的各个方面以及与之相关的一些优缺点。         本文的主要内容为 PLINQ 中的合并选项以及抛出和处理异常。         本教程对应学习工程:魔术师

    2024年02月13日
    浏览(35)
  • C++ 多线程编程和线程池

    c++ 多线程需要包含thread头文件 多线程调用函数代码如下 子线程和主线程同时执行,当子线程没执行完,主线程结束时,程序就会报错 join,主线程等待子线程执行完成后再执行,只能使用一次 detach,主程序结束,子线程会在后台执行 joinable,判断线程是否可以调用join和de

    2024年01月20日
    浏览(75)
  • 【C#】并行编程实战:使用 Visual Studio 调试任务

            并行编程可以提高应用程序的性能,但是调试起来会更困难,这一点在之前的章节中我们已经有了很直观的感受。对于程序而言,保证程序的正确性和保证性能同样重要。         本章将介绍可以在 Visual Studio 中的调试工具(包括 Thread 窗口、Tasks 窗口和 Con

    2024年02月15日
    浏览(44)
  • C++核心编程—类和对象,类的三大特性——封装、继承、多态

    纵有疾风起,人生不言弃。本文篇幅较长,如有错误请不吝赐教,感谢支持。 ①什么是对象? 生活中有各种各样的 事物 ,如人、动物、植物等在C++中将这些称为对象。 对象多种多样, 各种对象的属性也不相同 。 例如狗的品种,毛色,年龄等 各个对象都有自己的行为 ,例

    2024年02月07日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包