One-time initializations
Some C libraries are designed for dynamic initialization, in which the global initialization for the library is performed when the first procedure in the library is called.
In a single-threaded program, this is usually implemented using a static variable whose value is checked on entry to each routine, as in the following code fragment:
static int isInitialized = 0;
extern void Initialize();
int function()
{
if (isInitialized == 0) {
Initialize();
isInitialized = 1;
}
...
}
For dynamic library initialization in a multithreaded program, a simple initialization flag is not sufficient. This flag must be protected against modification by multiple threads simultaneously calling a library function. Protecting the flag requires the use of a mutex; however, mutexes must be initialized before they are used. Ensuring that the mutex is only initialized once requires a recursive solution to this problem.
To keep the same structure in a multithreaded program, use the pthread_once subroutine. Otherwise, library initialization must be accomplished by an explicit call to a library exported initialization function prior to any use of the library. The pthread_once subroutine also provides an alternative for initializing mutexes and condition variables.
Read the following to learn more about one-time initializations:
One-time initialization object
The uniqueness of the initialization is ensured by the one-time initialization object. It is a variable having the pthread_once_t data type. In AIX® and most other implementations of the threads library, the pthread_once_t data type is a structure.
A one-time initialization object is typically a global variable. It must be initialized with the PTHREAD_ONCE_INIT macro, as in the following example:
static pthread_once_t once_block = PTHREAD_ONCE_INIT;
The initialization can also be done in the initial thread or in any other thread. Several one-time initialization objects can be used in the same program. The only requirement is that the one-time initialization object be initialized with the macro.
One-time initialization routine
void init_routine();
The pthread_once subroutine does not provide a cancelation point. However, the initialization routine may provide cancelation points, and, if cancelability is enabled, the first thread calling the pthread_once subroutine may be canceled during the execution of the initialization routine. In this case, the routine is not considered as executed, and the next call to the pthread_once subroutine would result in recalling the initialization routine.
It is recommended to use cleanup handlers in one-time initialization routines, especially when performing non-idempotent operations, such as opening a file, locking a mutex, or allocating memory.
void
init_routine();
) would be written as follows: static pthread_once_t once_block = PTHREAD_ONCE_INIT;
extern void Initialize();
int function()
{
pthread_once(&once_block, Initialize);
...
}