section语句是用在sections语句里用来将sections语句里的代码划分成几个不同的段

#pragma omp [parallel] sections [子句]
{
   #pragma omp section
   {
            代码块
   } 
}
     当存在可选参数#pragma omp parallel sections时,块中的代码section才会并行处理,而#pragma omp  sections是串行的程序。详见下面的代码:
#include<stdio.h>
#include<stdlib.h>
#include<omp.h>
#include <unistd.h>
int main()
{ printf("parent threadid:%d\n",omp_get_thread_num());
#pragma omp sections
{
#pragma omp section
{
printf("section 0,threadid=%d\n",omp_get_thread_num());
sleep();
}
#pragma omp section
{
printf("section 1,threadid=%d\n",omp_get_thread_num());
//sleep(1);
}
#pragma omp section
{
printf("section 2,threadid=%d\n",omp_get_thread_num());
sleep();
}
}
#pragma omp parallel sections
{
#pragma omp section
{
printf("section 3,threadid=%d\n",omp_get_thread_num());
sleep();
}
#pragma omp section
{
printf("section 4,threadid=%d\n",omp_get_thread_num());
sleep();
}
#pragma omp section
{
printf("section 5,threadid=%d\n",omp_get_thread_num());
sleep();
}
} return ;
}
输出结果为:
parent threadid:0
section 0,threadid=0
section 1,threadid=0
section 2,threadid=0
section 3,threadid=0
section 4,threadid=2
section 5,threadid=1

针对上面的代码,首先应该明确下面几点:

1. sections之间是串行的。主线程把section0~2执行完之后才执行的第二个sections。

2.没有加parallel的sections里面的section是串行的,为此我专门sleep了一秒,结果显示0~2都是主线程做的。

3.第二个sections里面是并行的,进程编号分别为0,2,1。

问题来了,第二部分的0是不是主线程呢?还是第二部分新开的一个线程?为此需要真正输出每个线程在内核中的线程编号:

#include<stdio.h>
#include<stdlib.h>
#include<omp.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/syscall.h> int main()
{ printf("pid:%d,tid=%ld\n",getpid(),syscall(SYS_gettid));
#pragma omp sections
{
#pragma omp section
{
printf("section 0,tid=%ld\n",syscall(SYS_gettid));
sleep();
}
#pragma omp section
{
printf("section 1,tid=%ld\n",syscall(SYS_gettid));
//sleep(1);
}
#pragma omp section
{
printf("section 2,tid=%ld\n",syscall(SYS_gettid));
sleep();
}
}
#pragma omp parallel sections
{
#pragma omp section
{
printf("section 3,tid=%ld\n",syscall(SYS_gettid));
sleep();
}
#pragma omp section
{
printf("section 4,tid=%ld\n",syscall(SYS_gettid));
sleep();
}
#pragma omp section
{
printf("section 5,tid=%ld\n",syscall(SYS_gettid));
sleep();
}
} return ;
}

输出结果:

pid:7619,tid=7619
section 0,tid=7619
section 1,tid=7619
section 2,tid=7619
section 5,tid=7621
section 4,tid=7619
section 3,tid=7620

从结果中可以看出以下几点:

  1. OpenMP上说当程序执行到第二个sections是并行的,主线程是休眠的,一直等所有的子线程都执行完毕之后才唤醒,可是在第二个sections中有个线程id和主线程id一致?其实是不一致的,首先从两者的类型上来看,线程编号是long int的,而进程是int的,数字一致并不能说两者相同。另外一方面,在linuxthreads时代,线程称为轻量级进程(LWP),也就是每个线程就是个进程,每个线程(进程)ID不同;而从2.4.10后,采用NPTL(Native Posix Thread Library)的线程库, 各个线程同样是通过fork实现的,并且具备同一个父进程。
  2. 主进程id为7619,同时它又有个线程id也是7619,又一次证明在linux中线程进程差别不大。
  3. 猜测主线程并不是休眠,而是将原先的上下文保存,然后自身也作为并行的一份子进行并行程序的执行,当并行程序完成之后,再回复原先的上下文信息。

下面是一个比较复杂的例子

#include<stdio.h>
#include<stdlib.h>
#include<omp.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/syscall.h> int main()
{
#pragma omp parallel
{
printf("pid:%d,tid=%ld\n",getpid(),syscall(SYS_gettid));
#pragma omp sections
{
#pragma omp section
{
printf("section 0,tid=%ld\n",syscall(SYS_gettid));
//sleep(1);
}
#pragma omp section
{
printf("section 1,tid=%ld\n",syscall(SYS_gettid));
sleep();
}
#pragma omp section
{
printf("section 2,tid=%ld\n",syscall(SYS_gettid));
sleep();
}
}
#pragma omp sections
{
#pragma omp section
{
printf("section 3,tid=%ld\n",syscall(SYS_gettid));
sleep();
}
#pragma omp section
{
printf("section 4,tid=%ld\n",syscall(SYS_gettid));
sleep();
}
#pragma omp section
{
printf("section 5,tid=%ld\n",syscall(SYS_gettid));
sleep();
}
}
} return ;
}

输出结果:

pid:,tid=
section ,tid=
section ,tid=
pid:,tid=
section ,tid=
pid:,tid=
pid:,tid=
section ,tid=
section ,tid=
section ,tid=

#pragma omp parallel里面的代码是并行处理的,但是并不意味着代码要执行N次(其中N为核数),sections之间是串行的,而并行的实际部分是sections内部的代码。当线程7660在处理0,1时,因为section1休眠1s,所以section2在此期间会被新的线程进行处理。第一个sections真正处理完成之后,第二个sections才开始并行处理。

另外值得注意的是,printf并不是并行的函数,它是将结果输出到控制台中,可是控制台资源并不是共享的。当被某个线程占用之后,其余的线程只能等待,拿输出的结果为例。对于#pragma omp parallel里面的代码是并行的,可是线程之间还是有先后的次序的,次序和线程的创建时间有关,对于线程7660来说,本身就已经存在了,所以首先获得printf函数,而直到它执行section0里面的printf时,其他的线程还没有创建完毕,接着是setion1里面的printf,即使是这个时候有其他的线程创建完成了,也只能等待,在section1中,sleep了1秒钟,printf函数被新的线程使用,下面也如此。

OpenMp之sections用法的更多相关文章

  1. OpenMP初步(英文)

    Beginning OpenMP OpenMP provides a straight-forward interface to write software that can use multipl ...

  2. OpenMP并行编程应用—加速OpenCV图像拼接算法

    OpenMP是一种应用于多处理器程序设计的并行编程处理方案,它提供了对于并行编程的高层抽象.仅仅须要在程序中加入简单的指令,就能够编写高效的并行程序,而不用关心详细的并行实现细节.减少了并行编程的难度 ...

  3. Fortran并行计算的一些例子

    以下例子来自https://computing.llnl.gov/tutorials/openMP/exercise.html网站 一.打印线程(Hello world) C************* ...

  4. OpenMP用法大全

    OpenMP基本概念OpenMP是一种用于共享内存并行系统的多线程程序设计方案,支持的编程语言包括C.C++和Fortran.OpenMP提供了对并行算法的高层抽象描述,特别适合在多核CPU机器上的并 ...

  5. 链接脚本(Linker Script)用法解析(一) 关键字SECTIONS与MEMORY

    1.MEMORY关键字用于描述一个MCU ROM和RAM的内存地址分布(Memory Map),MEMORY中所做的内存描述主要用于SECTIONS中LMA和VMA的定义. 2.SECTIONS关键字 ...

  6. OpenMP之数值积分(求圆周率Pi)(sections)

    // Pi.cpp : 定义控制台应用程序的入口点. //求圆周率PI #include "stdafx.h" #include <windows.h> #includ ...

  7. 并行计算之OpenMP入门简介

    在上一篇文章中介绍了并行计算的基础概念,也顺便介绍了OpenMP. OpenMp提供了对于并行描述的高层抽象,降低了并行编程的难度和复杂度,这样程序员可以把更多的精力投入到并行算法本身,而非其具体实现 ...

  8. OpenMP并行程序设计

    1.fork/join并行执行模式的概念 2.OpenMP指令和库函数介绍 3.parallel 指令的用法 4.for指令的使用方法 5 sections和section指令的用法 1.fork/j ...

  9. openMP编程(上篇)之指令和锁

    openMP简介 openMP是一个编译器指令和库函数的集合,主要是为共享式存储计算机上的并行程序设计使用的. 当计算机升级到多核时,程序中创建的线程数量需要随CPU核数变化,如在CPU核数超过线程数 ...

随机推荐

  1. hdu 1028 Ignatius and the Princess III

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1028 题目大意:3=1+1+1=1+2=3 :4=4=1+1+1+1=1+2+1=1+3:所以3有3种 ...

  2. UIFontFamily

    Family: Hiragino Kaku Gothic ProN W3     Font: HiraKakuProN-W3 Family: Courier     Font: Courier     ...

  3. VS Bug 当获取其他项目的代码时, F5 无法进入调试模式. 也不报错....

    在64位的机子下, 被获用的项目使用X86时会出现. 就会出现   F5 无法进入调试模式. 也不报错.... 打断点也没有用. 在不加入X86项目的代码时, 又可以运行..   解决方案:   检查 ...

  4. JS通过ajax动态读取xml文件内容

    http://www.sharejs.com/codes/javascript/8178 HTML文件代码如下 <!DOCTYPE html> <html> <head& ...

  5. redis cluster安装部署(测试环境)

    redis 应用于web前端,做缓存和数据存取的速度是挺可观的,最近看了一些资料,手痒了,就弄了一个测试环境,两台方案,试用一下. ##Redis 集群部署## 一,方案调研: 参考博客: http: ...

  6. 云计算中iaas、paas、saas的区别和联系

    概念: iass : Infrastructure(基础设施)-as-a-Service, paas : Platform(平台)-as-a-Service, saas : Software(软件)- ...

  7. I/O复用:异步聊天

    一.I/O复用 在<TCP套接字编程>的同步聊天程序中,我们看到TCP客户同时处理两个输入:标准输入和TCP套接字.考虑在客户阻塞于标准输入fgets调用时,服务器进程被杀死,服务器TCP ...

  8. line-height 与垂直居中!

    在此之前,对于line-height 与垂直居中的问题,经常碰到. 比如,图片与span在同一个box中的时候,竟然会各种偏移.要想达到理想的效果真的是各种难. 有时间,决定认真的啃一啃. 一 lin ...

  9. SQL技术内幕-13 SQL优化方法论之分析实例级别的等待

    优化方法论的第一步是在实例级别上找出什么类型的等待占用了大部分的等待时间,这可以通过查询动态管理图(DMV,dynamic management view)sys.dm_os_wait_stats 运 ...

  10. BackgroundWorker组件

    BackgroundWorker组件封装了后台线程的操作,并且直接利用线程池,无需自己管理线程池等复杂问题. 它主要适用于 比如界面后台加载数据,进度显示,上传下载文件,日月结等 这些都是繁重的劳动, ...