|
Packit |
7cfc04 |
'\" et
|
|
Packit |
7cfc04 |
.TH PTHREAD_ONCE "3P" 2013 "IEEE/The Open Group" "POSIX Programmer's Manual"
|
|
Packit |
7cfc04 |
.SH PROLOG
|
|
Packit |
7cfc04 |
This manual page is part of the POSIX Programmer's Manual.
|
|
Packit |
7cfc04 |
The Linux implementation of this interface may differ (consult
|
|
Packit |
7cfc04 |
the corresponding Linux manual page for details of Linux behavior),
|
|
Packit |
7cfc04 |
or the interface may not be implemented on Linux.
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
.SH NAME
|
|
Packit |
7cfc04 |
pthread_once
|
|
Packit |
7cfc04 |
\(em dynamic package initialization
|
|
Packit |
7cfc04 |
.SH SYNOPSIS
|
|
Packit |
7cfc04 |
.LP
|
|
Packit |
7cfc04 |
.nf
|
|
Packit |
7cfc04 |
#include <pthread.h>
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
int pthread_once(pthread_once_t *\fIonce_control\fP,
|
|
Packit |
7cfc04 |
void (*\fIinit_routine\fP)(void));
|
|
Packit |
7cfc04 |
pthread_once_t \fIonce_control\fP = PTHREAD_ONCE_INIT;
|
|
Packit |
7cfc04 |
.fi
|
|
Packit |
7cfc04 |
.SH DESCRIPTION
|
|
Packit |
7cfc04 |
The first call to
|
|
Packit |
7cfc04 |
\fIpthread_once\fR()
|
|
Packit |
7cfc04 |
by any thread in a process, with a given
|
|
Packit |
7cfc04 |
.IR once_control ,
|
|
Packit |
7cfc04 |
shall call the
|
|
Packit |
7cfc04 |
.IR init_routine
|
|
Packit |
7cfc04 |
with no arguments. Subsequent calls of
|
|
Packit |
7cfc04 |
\fIpthread_once\fR()
|
|
Packit |
7cfc04 |
with the same
|
|
Packit |
7cfc04 |
.IR once_control
|
|
Packit |
7cfc04 |
shall not call the
|
|
Packit |
7cfc04 |
.IR init_routine .
|
|
Packit |
7cfc04 |
On return from
|
|
Packit |
7cfc04 |
\fIpthread_once\fR(),
|
|
Packit |
7cfc04 |
.IR init_routine
|
|
Packit |
7cfc04 |
shall have completed. The
|
|
Packit |
7cfc04 |
.IR once_control
|
|
Packit |
7cfc04 |
parameter shall determine whether the associated initialization
|
|
Packit |
7cfc04 |
routine has been called.
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
\fIpthread_once\fR()
|
|
Packit |
7cfc04 |
function is not a cancellation point. However, if
|
|
Packit |
7cfc04 |
.IR init_routine
|
|
Packit |
7cfc04 |
is a cancellation point and is canceled, the effect on
|
|
Packit |
7cfc04 |
.IR once_control
|
|
Packit |
7cfc04 |
shall be as if
|
|
Packit |
7cfc04 |
\fIpthread_once\fR()
|
|
Packit |
7cfc04 |
was never called.
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
The constant PTHREAD_ONCE_INIT is defined in the
|
|
Packit |
7cfc04 |
.IR <pthread.h>
|
|
Packit |
7cfc04 |
header.
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
The behavior of
|
|
Packit |
7cfc04 |
\fIpthread_once\fR()
|
|
Packit |
7cfc04 |
is undefined if
|
|
Packit |
7cfc04 |
.IR once_control
|
|
Packit |
7cfc04 |
has automatic storage duration or is not initialized by
|
|
Packit |
7cfc04 |
PTHREAD_ONCE_INIT.
|
|
Packit |
7cfc04 |
.SH "RETURN VALUE"
|
|
Packit |
7cfc04 |
Upon successful completion,
|
|
Packit |
7cfc04 |
\fIpthread_once\fR()
|
|
Packit |
7cfc04 |
shall return zero; otherwise, an error number shall be returned to
|
|
Packit |
7cfc04 |
indicate the error.
|
|
Packit |
7cfc04 |
.SH ERRORS
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
\fIpthread_once\fR()
|
|
Packit |
7cfc04 |
function shall not return an error code of
|
|
Packit |
7cfc04 |
.BR [EINTR] .
|
|
Packit |
7cfc04 |
.LP
|
|
Packit |
7cfc04 |
.IR "The following sections are informative."
|
|
Packit |
7cfc04 |
.SH EXAMPLES
|
|
Packit |
7cfc04 |
None.
|
|
Packit |
7cfc04 |
.SH "APPLICATION USAGE"
|
|
Packit |
7cfc04 |
None.
|
|
Packit |
7cfc04 |
.SH RATIONALE
|
|
Packit |
7cfc04 |
Some C libraries are designed for dynamic initialization. That is, the
|
|
Packit |
7cfc04 |
global initialization for the library is performed when the first
|
|
Packit |
7cfc04 |
procedure in the library is called. In a single-threaded program, this
|
|
Packit |
7cfc04 |
is normally implemented using a static variable whose value is checked
|
|
Packit |
7cfc04 |
on entry to a routine, as follows:
|
|
Packit |
7cfc04 |
.sp
|
|
Packit |
7cfc04 |
.RS 4
|
|
Packit |
7cfc04 |
.nf
|
|
Packit |
7cfc04 |
\fB
|
|
Packit |
7cfc04 |
static int random_is_initialized = 0;
|
|
Packit |
5c42c1 |
extern void initialize_random();
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
int random_function()
|
|
Packit |
7cfc04 |
{
|
|
Packit |
7cfc04 |
if (random_is_initialized == 0) {
|
|
Packit |
7cfc04 |
initialize_random();
|
|
Packit |
7cfc04 |
random_is_initialized = 1;
|
|
Packit |
7cfc04 |
}
|
|
Packit |
7cfc04 |
... /* Operations performed after initialization. */
|
|
Packit |
7cfc04 |
}
|
|
Packit |
7cfc04 |
.fi \fR
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
.RE
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
To keep the same structure in a multi-threaded program, a new primitive
|
|
Packit |
7cfc04 |
is needed. Otherwise, library initialization has to be accomplished by
|
|
Packit |
7cfc04 |
an explicit call to a library-exported initialization function prior to
|
|
Packit |
7cfc04 |
any use of the library.
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
For dynamic library initialization in a multi-threaded process, a
|
|
Packit |
7cfc04 |
simple initialization flag is not sufficient; the flag needs to be
|
|
Packit |
7cfc04 |
protected against modification by multiple threads simultaneously
|
|
Packit |
7cfc04 |
calling into the library. Protecting the flag requires the use of a
|
|
Packit |
7cfc04 |
mutex; however, mutexes have to be initialized before they are used.
|
|
Packit |
7cfc04 |
Ensuring that the mutex is only initialized once requires a recursive
|
|
Packit |
7cfc04 |
solution to this problem.
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
The use of
|
|
Packit |
7cfc04 |
\fIpthread_once\fR()
|
|
Packit |
7cfc04 |
not only supplies an implementation-guaranteed means of dynamic
|
|
Packit |
7cfc04 |
initialization, it provides an aid to the reliable construction of
|
|
Packit |
7cfc04 |
multi-threaded and realtime systems. The preceding example then
|
|
Packit |
7cfc04 |
becomes:
|
|
Packit |
7cfc04 |
.sp
|
|
Packit |
7cfc04 |
.RS 4
|
|
Packit |
7cfc04 |
.nf
|
|
Packit |
7cfc04 |
\fB
|
|
Packit |
7cfc04 |
#include <pthread.h>
|
|
Packit |
7cfc04 |
static pthread_once_t random_is_initialized = PTHREAD_ONCE_INIT;
|
|
Packit |
5c42c1 |
extern void initialize_random();
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
int random_function()
|
|
Packit |
7cfc04 |
{
|
|
Packit |
7cfc04 |
(void) pthread_once(&random_is_initialized, initialize_random);
|
|
Packit |
7cfc04 |
... /* Operations performed after initialization. */
|
|
Packit |
7cfc04 |
}
|
|
Packit |
7cfc04 |
.fi \fR
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
.RE
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
Note that a
|
|
Packit |
7cfc04 |
.BR pthread_once_t
|
|
Packit |
7cfc04 |
cannot be an array because some compilers do not accept the construct
|
|
Packit |
7cfc04 |
\fB&<array_name>\fP.
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
If an implementation detects that the value specified by the
|
|
Packit |
7cfc04 |
.IR once_control
|
|
Packit |
7cfc04 |
argument to
|
|
Packit |
7cfc04 |
\fIpthread_once\fR()
|
|
Packit |
7cfc04 |
does not refer to a
|
|
Packit |
7cfc04 |
.BR pthread_once_t
|
|
Packit |
7cfc04 |
object initialized by PTHREAD_ONCE_INIT, it is recommended that the
|
|
Packit |
7cfc04 |
function should fail and report an
|
|
Packit |
7cfc04 |
.BR [EINVAL]
|
|
Packit |
7cfc04 |
error.
|
|
Packit |
7cfc04 |
.SH "FUTURE DIRECTIONS"
|
|
Packit |
7cfc04 |
None.
|
|
Packit |
7cfc04 |
.SH "SEE ALSO"
|
|
Packit |
7cfc04 |
The Base Definitions volume of POSIX.1\(hy2008,
|
|
Packit |
7cfc04 |
.IR "\fB<pthread.h>\fP"
|
|
Packit |
7cfc04 |
.SH COPYRIGHT
|
|
Packit |
7cfc04 |
Portions of this text are reprinted and reproduced in electronic form
|
|
Packit |
7cfc04 |
from IEEE Std 1003.1, 2013 Edition, Standard for Information Technology
|
|
Packit |
7cfc04 |
-- Portable Operating System Interface (POSIX), The Open Group Base
|
|
Packit |
7cfc04 |
Specifications Issue 7, Copyright (C) 2013 by the Institute of
|
|
Packit |
7cfc04 |
Electrical and Electronics Engineers, Inc and The Open Group.
|
|
Packit |
7cfc04 |
(This is POSIX.1-2008 with the 2013 Technical Corrigendum 1 applied.) In the
|
|
Packit |
7cfc04 |
event of any discrepancy between this version and the original IEEE and
|
|
Packit |
7cfc04 |
The Open Group Standard, the original IEEE and The Open Group Standard
|
|
Packit |
7cfc04 |
is the referee document. The original Standard can be obtained online at
|
|
Packit |
7cfc04 |
http://www.unix.org/online.html .
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
Any typographical or formatting errors that appear
|
|
Packit |
7cfc04 |
in this page are most likely
|
|
Packit |
7cfc04 |
to have been introduced during the conversion of the source files to
|
|
Packit |
7cfc04 |
man page format. To report such errors, see
|
|
Packit |
7cfc04 |
https://www.kernel.org/doc/man-pages/reporting_bugs.html .
|