OpenMP Directives: Synchronization Constructs: CRITICAL Directive

Purpose:

The CRITICAL directive specifies a region of code that must be executed by only one thread at a time.

Format:

Fortran

!$OMP CRITICAL [ name ]

   block

!$OMP END CRITICAL [ name ]

C/C++

#pragma omp critical [ name ]  newline

   structured_block

Notes:

If a thread is currently executing inside a CRITICAL region and another thread reaches that CRITICAL region and attempts to execute it, it will block until the first thread exits that CRITICAL region.

The optional name enables multiple different CRITICAL regions to exist:

Names act as global identifiers. Different CRITICAL regions with the same name are treated as the same region. All CRITICAL sections which are unnamed, are treated as the same section.

Restrictions:

It is illegal to branch into or out of a CRITICAL block.

Fortran only: The names of critical constructs are global entities of the program. If a name conflicts with any other entity, the behavior of the program is unspecified.

Example: CRITICAL Construct

All threads in the team will attempt to execute in parallel, however, because of the CRITICAL construct surrounding the increment of x, only one thread will be able to read/increment/write x at any time.

Fortran - CRITICAL Directive Example

      PROGRAM CRITICAL

      INTEGER X
      X = 0

!$OMP PARALLEL SHARED(X)

!$OMP CRITICAL 
      X = X + 1
!$OMP END CRITICAL 

!$OMP END PARALLEL 

      END

C / C++ - critical Directive Example

#include 

main()
{

int x;
x = 0;

#pragma omp parallel shared(x) 
  {

  #pragma omp critical 
  x = x + 1;

  }  /* end of parallel section */

}
</pre>