您可以使用 taskwait 或 taskgroup 指令同步任务。
当线程遇到 taskwait 构造时,当前任务会暂停,直到它在 taskwait 区域前生成的所有子任务均已完成执行为止。
当线程遇到 taskgroup 构造时,它将开始执行 taskgroup 区域。在 taskgroup 区域末尾,当前任务暂停,直到它在 taskgroup 区域中生成的所有子任务及其所有子孙任务均已完成执行为止。
请注意 taskwait 与 taskgroup 之间的不同。使用 taskwait,当前任务仅等待其子任务。使用 taskgroup,当前任务不仅等待在 taskgroup 中生成的子任务,还等待这些子任务的所有子孙任务。下面两个示例介绍了二者之间的差异。
示例 7 taskwait 示例% cat -n taskwait.c
1 #include <omp.h>
2 #include <stdio.h>
3 #include <unistd.h>
4
5 int main()
6 {
7 #pragma omp parallel
8 #pragma omp single
9 {
10 #pragma omp task
11 {
12 #pragma omp critical
13 printf ("Task 1\n");
14
15 #pragma omp task
16 {
17 sleep(1);
18 #pragma omp critical
19 printf ("Task 2\n");
20 }
21 }
22
23 #pragma omp taskwait
24
25 #pragma omp task
26 {
27 #pragma omp critical
28 printf ("Task 3\n");
29 }
30 }
31
32 return 0;
33 }
示例 8 taskgroup 示例
% cat -n taskgroup.c
1 #include <omp.h>
2 #include <stdio.h>
3 #include <unistd.h>
4
5 int main()
6 {
7 #pragma omp parallel
8 #pragma omp single
9 {
10 #pragma omp taskgroup
11 {
12 #pragma omp task
13 {
14 #pragma omp critical
15 printf ("Task 1\n");
16
17 #pragma omp task
18 {
19 sleep(1);
20 #pragma omp critical
21 printf ("Task 2\n");
22 }
23 }
24 } /* end taskgroup */
25
26 #pragma omp task
27 {
28 #pragma omp critical
29 printf ("Task 3\n");
30 }
31 }
32
33 return 0;
34 }
虽然 taskwait.c 和 taskgroup.c 的源代码几乎相同,但是 taskwait.c 在第 23 行有 taskwait 指令,而 taskgroup.c 在第 10 行有包含任务 1 和任务 2 的 taskgroup 构造。在这两个程序中,taskwait 和 taskgroup 指令同步任务 1 和任务 3 的执行;不同之处在于它们是否同步任务 2 和任务 3 的执行。
在使用 taskwait.c 的情况下,任务 2 不是 taskwait 区域绑定到的并行区域所生成的隐式任务的子任务。因此,任务 2 不必在 taskwait 区域末尾完成。可以在完成任务 2 之前调度任务 3。
对于 taskgroup.c,任务 2 是任务 1 的子任务,该任务是在 taskgroup 区域中生成的。因此,任务 2 必须在 taskgroup 区域末尾完成,然后才能遇到和调度任务 3。