Multithreaded Programming Guide

Using Barrier Synchronization

In cases where you must wait for a number of tasks to be completed before an overall task can proceed, barrier synchronization can be used. POSIX threads specifies a synchronization object called a barrier, along with barrier functions. The functions create the barrier, specifying the number of threads that are synchronizing on the barrier, and set up threads to perform tasks and wait at the barrier until all the threads reach the barrier. When the last thread arrives at the barrier, all the threads resume execution.

See Parallelizing a Loop on a Shared-Memory Parallel Computer for more about barrier synchronization.

Initializing a Synchronization Barrier

Use pthread_barrier_init(3C) to allocate resources for a barrier and initialize its attributes.

pthread_barrier_init() Syntax

int pthread_barrier_init(pthread_barrier_t  *barrier, 
          const pthread_barrierattr_t *restrict attr, 
          unsigned count);
#include <pthread.h> 
pthread_barrier_t barrier; 
pthread_barrierattr_t attr;
unsigned count;
int ret; 
ret = pthread_barrier_init(&barrier, &attr, count);

The pthread_barrier_init() function allocates any resources required to use the barrier referenced by barrier and initializes the barrier with attributes referenced by attr. If attr is NULL, the default barrier attributes are used; the effect is the same as passing the address of a default barrier attributes object. The count argument specifies the number of threads that must call pthread_barrier_wait() before any of them successfully return from the call. The value specified by count must be greater than 0.

pthread_barrier_init() Return Values

pthread_barrier_init() returns zero after completing successfully. Any other return value indicates that an error occurred. If the following condition occurs, the function fails and returns the corresponding value.


EINVAL

Description:

The value specified by count is equal to 0, or the value specified by attr is invalid


EAGAIN

Description:

The system lacks the necessary resources to initialize another barrier.


ENOMEM

Description:

Insufficient memory exists to initialize the barrier.


EBUSY

Description:

There was an attempt to destroy a barrier while it is in use (for example, while being used in a pthread_barrier_wait() call) by another thread.

Waiting for Threads to Synchronize at a Barrier

Use pthread_barrier_wait(3C) to synchronize threads at a specified barrier. The calling thread blocks until the required number of threads have called pthread_barrier_wait() specifying the barrier. The number of threads is specified in the pthread_barrier_init() function.

When the required number of threads have called pthread_barrier_wait() specifying the barrier, the constant PTHREAD_BARRIER_SERIAL_THREAD is returned to one unspecified thread and 0 is returned to each of the remaining threads. The barrier is then reset to the state it had as a result of the most recent pthread_barrier_init() function that referenced it.

pthread_barrier_wait() Syntax

int pthread_barrier_wait(pthread_barrier_t  *barrier);
#include <pthread.h> 
pthread_barrier_t barrier; 
int ret; 
ret = pthread_barrier_wait(&barrier);

pthread_barrier_wait() Return Values

When pthread_barrier_wait() completes successfully, the function returns PTHREAD_BARRIER_SERIAL_THREAD, which is defined in pthread.h, for one arbitrary thread synchronized at the barrier. The function returns zero for each of the other threads. Otherwise an error code is returned.


EINVAL

Description:

The value specified by barrier does not refer to an initialized barrier object.

Destroying a Synchronization Barrier

When a barrier is no longer needed, it should be destroyed. Use the pthread_barrier_destroy(3C) function to destroy the barrier referenced by barrier and release any resources used by the barrier.

pthread_barrier_destroy Syntax

int pthread_barrier_destroy(pthread_barrier_t *barrier);
#include <pthread.h> 
pthread_barrier_t barrier; 
int ret; 
ret = pthread_barrier_destroy(&barrier);

pthread_barrier_destroy Return Values

pthread_barrier_destroy() returns zero after completing successfully. Any other return value indicates that an error occurred. If the following condition occurs, the function fails and returns the corresponding value.


EINVAL

Description:

Indicates that the value of barrier was not valid.


EBUSY

Description:

An attempt was made to destroy a barrier while it is in use (for example, while being used in a pthread_barrier_wait() by another thread.

Initializing a Barrier Attributes Object

The pthread_barrierattr_init(3C) function initializes a barrier attributes object attr with the default values for the attributes defined for the object by the implementation. Currently, only the process-shared attribute is provided, and the pthread_barrierattr_getpshared() and pthread_barrierattr_setpshared() functions are used to get and set the attribute.

After a barrier attributes object has been used to initialize one or more barriers, any function affecting the attributes object (including destruction) does not affect any previously initialized barrier.

pthread_barrierattr_init() Syntax

int pthread_barrierattr_init(pthread_barrierattr_t *attr);
#include <pthread.h> 
pthread_barrierattr_t attr; 
int ret; 
ret = pthread_barrierattr_init(&attr);

pthread_barrierattr_init() Return Values

pthread_barrierattr_init() returns zero after completing successfully. Any other return value indicates that an error occurred. If the following condition occurs, the function fails and returns the corresponding value.


ENOMEM

Description:

Insufficient memory exists to initialize the barrier attributes object.

Setting a Barrier Process-Shared Attribute

The pthread_barrierattr_setpshared() function sets the process-shared attribute in an initialized attributes object referenced by attr. The process-shared attribute can have the following values:

PTHREAD_PROCESS_PRIVATE

The barrier can only be operated upon by threads created within the same process as the thread that initialized the barrier. This is the default value of the process-shared attribute.

PTHREAD_PROCESS_SHARED

The barrier can be operated upon by any thread that has access to the memory where the barrier is allocated.

pthread_barrierattr_setpshared() Syntax

int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared);

pthread_barrierattr_setpshared() Return Values

pthread_barrierattr_setpshared() returns zero after completing successfully. Any other return value indicates that an error occurred. If the following condition occurs, the function fails and returns the corresponding value.


EINVAL

Description:

Indicates that the value of attr was not valid, or the new value specified for the pshared is not valid.

Getting a Barrier Process-Shared Attribute

The pthread_barrierattr_getpshared(3C) function obtains the value of the process-shared attribute from the attributes object referenced by attr. The value is set by the pthread_barrierattr_setpshared() function.

pthread_barrierattr_getpshared() Syntax

int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict attr, 
          int *restrict pshared);

pthread_barrierattr_getpshared() Return Values

pthread_barrierattr_getpshared() returns zero after completing successfully, and stores the value of the process-shared attribute of attr into the object referenced by the pshared parameter. Any other return value indicates that an error occurred. If the following condition occurs, the function fails and returns the corresponding value.


EINVAL

Description:

Indicates that the value of attr was not valid.

Destroying a Barrier Attributes Object

The pthread_barrierattr_destroy() function destroys a barrier attributes object. A destroyed attr attributes object can be reinitialized using pthread_barrierattr_init().

After a barrier attributes object has been used to initialize one or more barriers, destroying the object does not affect any previously initialized barrier.

pthread_barrierattr_destroy() Syntax

#include <pthread.h>

int  pthread_barrierattr_destroy(pthread_barrierattr_t *attr);

pthread_barrierattr_destroy() Return Values

pthread_barrierattr_destroy() returns zero after completing successfully. Any other return value indicates that an error occurred. If the following condition occurs, the function fails and returns the corresponding value.


EINVAL

Description:

Indicates that the value of attr was not valid.