# pthread_once

## PROLOG



           This manual page is part of the POSIX Programmer's Manual.  The
           Linux implementation of this interface may differ (consult the
           corresponding Linux manual page for details of Linux behavior), or
           the interface may not be implemented on Linux.
    


## NAME



           pthread_once — dynamic package initialization
    


## SYNOPSIS



           #include <pthread.h>
    
           int pthread_once(pthread_once_t *_once_control_ ,
               void (*_init_routine_)(void));
           pthread_once_t _once_control_ = PTHREAD_ONCE_INIT;
    


## DESCRIPTION



           The first call to _pthread_once_() by any thread in a process, with
           a given _once_control_ , shall call the _init_routine_ with no
           arguments. Subsequent calls of _pthread_once_() with the same
           _once_control_ shall not call the _init_routine_.  On return from
           _pthread_once_(), _init_routine_ shall have completed. The
           _once_control_ parameter shall determine whether the associated
           initialization routine has been called.
    
           The _pthread_once_() function is not a cancellation point. However,
           if _init_routine_ is a cancellation point and is canceled, the
           effect on _once_control_ shall be as if _pthread_once_() was never
           called.
    
           If the call to _init_routine_ is terminated by a call to _longjmp_(),
           __longjmp_(), or _siglongjmp_(), the behavior is undefined.
    
           The constant PTHREAD_ONCE_INIT is defined in the _< pthread.h>_
           header.
    
           The behavior of _pthread_once_() is undefined if _once_control_ has
           automatic storage duration or is not initialized by
           PTHREAD_ONCE_INIT.
    


## RETURN VALUE



           Upon successful completion, _pthread_once_() shall return zero;
           otherwise, an error number shall be returned to indicate the
           error.
    


## ERRORS



           The _pthread_once_() function shall not return an error code of
           **[EINTR]**.
    
           _The following sections are informative._
    


## EXAMPLES



           None.
    


## APPLICATION USAGE



           If _init_routine_ recursively calls _pthread_once_() with the same
           _once_control_ , the recursive call will not call the specified
           _init_routine_ , and thus the specified _init_routine_ will not
           complete, and thus the recursive call to _pthread_once_() will not
           return. Use of _longjmp_(), __longjmp_(), or _siglongjmp_() within an
           _init_routine_ to jump to a point outside of _init_routine_ prevents
           _init_routine_ from returning.
    


## RATIONALE



           Some C libraries are designed for dynamic initialization. That is,
           the global initialization for the library is performed when the
           first procedure in the library is called. In a single-threaded
           program, this is normally implemented using a static variable
           whose value is checked on entry to a routine, as follows:
    
               static int random_is_initialized = 0;
               extern void initialize_random(void);
    
               int random_function()
               {
                   if (random_is_initialized == 0) {
                       initialize_random();
                       random_is_initialized = 1;
                   }
                   ... /* Operations performed after initialization. */
               }
    
           To keep the same structure in a multi-threaded program, a new
           primitive is needed. Otherwise, library initialization has to be
           accomplished by an explicit call to a library-exported
           initialization function prior to any use of the library.
    
           For dynamic library initialization in a multi-threaded process, if
           an initialization flag is used the flag needs to be protected
           against modification by multiple threads simultaneously calling
           into the library. This can be done by using a mutex (initialized
           by assigning PTHREAD_MUTEX_INITIALIZER). However, the better
           solution is to use _pthread_once_() which is designed for exactly
           this purpose, as follows:
    
               #include <pthread.h>
               static pthread_once_t random_is_initialized = PTHREAD_ONCE_INIT;
               extern void initialize_random(void);
    
               int random_function()
               {
                   (void) pthread_once(&random_is_initialized, initialize_random);
                   ... /* Operations performed after initialization. */
               }
    
           If an implementation detects that the value specified by the
           _once_control_ argument to _pthread_once_() does not refer to a
           **pthread_once_t** object initialized by PTHREAD_ONCE_INIT, it is
           recommended that the function should fail and report an **[EINVAL]**
           error.
    


## FUTURE DIRECTIONS



           None.
    


* * *