标签:
section语句是用在sections语句里用来将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(1); } #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(1); } } #pragma omp parallel sections { #pragma omp section { printf("section 3,threadid=%d\n",omp_get_thread_num()); sleep(1); } #pragma omp section { printf("section 4,threadid=%d\n",omp_get_thread_num()); sleep(1); } #pragma omp section { printf("section 5,threadid=%d\n",omp_get_thread_num()); sleep(1); } } return 0; }
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(1); } #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(1); } } #pragma omp parallel sections { #pragma omp section { printf("section 3,tid=%ld\n",syscall(SYS_gettid)); sleep(1); } #pragma omp section { printf("section 4,tid=%ld\n",syscall(SYS_gettid)); sleep(1); } #pragma omp section { printf("section 5,tid=%ld\n",syscall(SYS_gettid)); sleep(1); } } return 0; }
输出结果:
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
从结果中可以看出以下几点:
下面是一个比较复杂的例子
#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(1); } #pragma omp section { printf("section 2,tid=%ld\n",syscall(SYS_gettid)); sleep(1); } } #pragma omp sections { #pragma omp section { printf("section 3,tid=%ld\n",syscall(SYS_gettid)); sleep(1); } #pragma omp section { printf("section 4,tid=%ld\n",syscall(SYS_gettid)); sleep(1); } #pragma omp section { printf("section 5,tid=%ld\n",syscall(SYS_gettid)); sleep(1); } } } return 0; }
输出结果:
pid:7660,tid=7660 section 0,tid=7660 section 1,tid=7660 pid:7660,tid=7662 section 2,tid=7662 pid:7660,tid=7663 pid:7660,tid=7661 section 3,tid=7660 section 5,tid=7661 section 4,tid=7662
#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函数被新的线程使用,下面也如此。
标签:
原文地址:http://www.cnblogs.com/wzyj/p/4501348.html