1PTHREAD_ONCE(3P)           POSIX Programmer's Manual          PTHREAD_ONCE(3P)
2
3
4

PROLOG

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

NAME

12       pthread_once — dynamic package initialization
13

SYNOPSIS

15       #include <pthread.h>
16
17       int pthread_once(pthread_once_t *once_control,
18           void (*init_routine)(void));
19       pthread_once_t once_control = PTHREAD_ONCE_INIT;
20

DESCRIPTION

22       The first call to pthread_once() by any thread in  a  process,  with  a
23       given once_control, shall call the init_routine with no arguments. Sub‐
24       sequent calls of pthread_once() with the same  once_control  shall  not
25       call  the  init_routine.   On  return from pthread_once(), init_routine
26       shall  have  completed.  The  once_control  parameter  shall  determine
27       whether the associated initialization routine has been called.
28
29       The  pthread_once()  function  is not a cancellation point. However, if
30       init_routine is a cancellation point and is  canceled,  the  effect  on
31       once_control shall be as if pthread_once() was never called.
32
33       If  the  call  to  init_routine  is  terminated by a call to longjmp(),
34       _longjmp(), or siglongjmp(), the behavior is undefined.
35
36       The constant PTHREAD_ONCE_INIT is defined in the <pthread.h> header.
37
38       The behavior of pthread_once() is undefined if once_control  has  auto‐
39       matic storage duration or is not initialized by PTHREAD_ONCE_INIT.
40

RETURN VALUE

42       Upon  successful  completion,  pthread_once() shall return zero; other‐
43       wise, an error number shall be returned to indicate the error.
44

ERRORS

46       The pthread_once() function shall not return an error code of [EINTR].
47
48       The following sections are informative.
49

EXAMPLES

51       None.
52

APPLICATION USAGE

54       If  init_routine  recursively  calls  pthread_once()  with   the   same
55       once_control,  the recursive call will not call the specified init_rou‐
56       tine, and thus the specified init_routine will not complete,  and  thus
57       the recursive call to pthread_once() will not return. Use of longjmp(),
58       _longjmp(), or siglongjmp() within an init_routine to jump to  a  point
59       outside of init_routine prevents init_routine from returning.
60

RATIONALE

62       Some  C libraries are designed for dynamic initialization. That is, the
63       global initialization for the library is performed when the first  pro‐
64       cedure  in the library is called. In a single-threaded program, this is
65       normally implemented using a static variable whose value is checked  on
66       entry to a routine, as follows:
67
68
69           static int random_is_initialized = 0;
70           extern void initialize_random(void);
71
72           int random_function()
73           {
74               if (random_is_initialized == 0) {
75                   initialize_random();
76                   random_is_initialized = 1;
77               }
78               ... /* Operations performed after initialization. */
79           }
80
81       To keep the same structure in a multi-threaded program, a new primitive
82       is needed. Otherwise, library initialization has to be accomplished  by
83       an explicit call to a library-exported initialization function prior to
84       any use of the library.
85
86       For dynamic library initialization in a multi-threaded process,  if  an
87       initialization flag is used the flag needs to be protected against mod‐
88       ification by multiple threads simultaneously calling into the  library.
89       This   can   be  done  by  using  a  mutex  (initialized  by  assigning
90       PTHREAD_MUTEX_INITIALIZER). However, the  better  solution  is  to  use
91       pthread_once() which is designed for exactly this purpose, as follows:
92
93
94           #include <pthread.h>
95           static pthread_once_t random_is_initialized = PTHREAD_ONCE_INIT;
96           extern void initialize_random(void);
97
98           int random_function()
99           {
100               (void) pthread_once(&random_is_initialized, initialize_random);
101               ... /* Operations performed after initialization. */
102           }
103
104       If  an implementation detects that the value specified by the once_con‐
105       trol argument to pthread_once() does  not  refer  to  a  pthread_once_t
106       object  initialized  by  PTHREAD_ONCE_INIT,  it is recommended that the
107       function should fail and report an [EINVAL] error.
108

FUTURE DIRECTIONS

110       None.
111

SEE ALSO

113       The Base Definitions volume of POSIX.1‐2017, <pthread.h>
114
116       Portions of this text are reprinted and reproduced in  electronic  form
117       from  IEEE Std 1003.1-2017, Standard for Information Technology -- Por‐
118       table Operating System Interface (POSIX), The Open Group Base  Specifi‐
119       cations  Issue  7, 2018 Edition, Copyright (C) 2018 by the Institute of
120       Electrical and Electronics Engineers, Inc and The Open Group.   In  the
121       event of any discrepancy between this version and the original IEEE and
122       The Open Group Standard, the original IEEE and The Open Group  Standard
123       is  the  referee document. The original Standard can be obtained online
124       at http://www.opengroup.org/unix/online.html .
125
126       Any typographical or formatting errors that appear  in  this  page  are
127       most likely to have been introduced during the conversion of the source
128       files to man page format. To report such errors,  see  https://www.ker
129       nel.org/doc/man-pages/reporting_bugs.html .
130
131
132
133IEEE/The Open Group                  2017                     PTHREAD_ONCE(3P)
Impressum