Go to main content
Oracle® Developer Studio 12.5: OpenMP API User's Guide

Exit Print View

Updated: July 2016
 
 

4.6 Task Synchronization Using taskwait and taskgroup

You can synchronize tasks by using the taskwait or taskgroup directives.

When a thread encounters a taskwait construct, the current task is suspended until all child tasks that it generated before the taskwait region complete execution.

When a thread encounters a taskgroup construct, it commences to execute the taskgroup region. At the end of the taskgroup region, the current task is suspended until all child tasks that it generated in the taskgroup region and all of their descendant tasks complete execution.

Note the difference between taskwait and taskgroup. With taskwait, the current task waits only for its child tasks. With taskgroup, the current task waits not only for the child tasks generated in the taskgroup but also for all the descendants of those child tasks. The following two examples illustrate the difference.

Example 7  taskwait Example
% 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  }
Example 8  taskgroup Example
% 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  }

Although the source codes of taskwait.c and taskgroup.c are almost the same, taskwait.c has a taskwait directive at line 23, whereas taskgroup.c has a taskgroup construct at line 10 that contains Task 1 and Task 2. In both programs, the taskwait and taskgroup directives synchronize the execution of Task 1 and Task 3; the difference is in whether they synchronize the execution of Task 2 and Task 3.

In the case of taskwait.c, Task 2 is not a child task of the implicit task generated by the parallel region to which the taskwait region is bound. So, Task 2 does not have to finish by the end of the taskwait region. Task 3 can be scheduled before the completion of Task 2.

In the case of taskgroup.c, Task 2 is a child task of Task 1, which is generated in the taskgroup region. So, Task 2 has to finish by the end of the taskgroup region, before Task 3 is encountered and scheduled.