mirror of https://github.com/mkerrisk/man-pages
342 lines
10 KiB
Plaintext
342 lines
10 KiB
Plaintext
.\" Copyright (c) 2001-2003 The Open Group, All Rights Reserved
|
|
.TH "PTHREAD_MUTEXATTR_DESTROY" P 2003 "IEEE/The Open Group" "POSIX Programmer's Manual"
|
|
.\" pthread_mutexattr_destroy
|
|
.SH NAME
|
|
pthread_mutexattr_destroy, pthread_mutexattr_init \- destroy and initialize
|
|
the mutex attributes object
|
|
.SH SYNOPSIS
|
|
.LP
|
|
\fB#include <pthread.h>
|
|
.br
|
|
.sp
|
|
int pthread_mutexattr_destroy(pthread_mutexattr_t *\fP\fIattr\fP\fB);
|
|
.br
|
|
int pthread_mutexattr_init(pthread_mutexattr_t *\fP\fIattr\fP\fB);
|
|
\fP
|
|
\fB
|
|
.br
|
|
\fP
|
|
.SH DESCRIPTION
|
|
.LP
|
|
The \fIpthread_mutexattr_destroy\fP() function shall destroy a mutex
|
|
attributes object; the object becomes, in effect,
|
|
uninitialized. An implementation may cause \fIpthread_mutexattr_destroy\fP()
|
|
to set the object referenced by \fIattr\fP to an
|
|
invalid value. A destroyed \fIattr\fP attributes object can be reinitialized
|
|
using \fIpthread_mutexattr_init\fP(); the results of
|
|
otherwise referencing the object after it has been destroyed are undefined.
|
|
.LP
|
|
The \fIpthread_mutexattr_init\fP() function shall initialize a mutex
|
|
attributes object \fIattr\fP with the default value for
|
|
all of the attributes defined by the implementation.
|
|
.LP
|
|
Results are undefined if \fIpthread_mutexattr_init\fP() is called
|
|
specifying an already initialized \fIattr\fP attributes
|
|
object.
|
|
.LP
|
|
After a mutex attributes object has been used to initialize one or
|
|
more mutexes, any function affecting the attributes object
|
|
(including destruction) shall not affect any previously initialized
|
|
mutexes.
|
|
.SH RETURN VALUE
|
|
.LP
|
|
Upon successful completion, \fIpthread_mutexattr_destroy\fP() and
|
|
\fIpthread_mutexattr_init\fP() shall return zero; otherwise,
|
|
an error number shall be returned to indicate the error.
|
|
.SH ERRORS
|
|
.LP
|
|
The \fIpthread_mutexattr_destroy\fP() function may fail if:
|
|
.TP 7
|
|
.B EINVAL
|
|
The value specified by \fIattr\fP is invalid.
|
|
.sp
|
|
.LP
|
|
The \fIpthread_mutexattr_init\fP() function shall fail if:
|
|
.TP 7
|
|
.B ENOMEM
|
|
Insufficient memory exists to initialize the mutex attributes object.
|
|
.sp
|
|
.LP
|
|
These functions shall not return an error code of [EINTR].
|
|
.LP
|
|
\fIThe following sections are informative.\fP
|
|
.SH EXAMPLES
|
|
.LP
|
|
None.
|
|
.SH APPLICATION USAGE
|
|
.LP
|
|
None.
|
|
.SH RATIONALE
|
|
.LP
|
|
See \fIpthread_attr_init\fP() for a general explanation of attributes.
|
|
Attributes objects
|
|
allow implementations to experiment with useful extensions and permit
|
|
extension of this volume of IEEE\ Std\ 1003.1-2001
|
|
without changing the existing functions. Thus, they provide for future
|
|
extensibility of this volume of
|
|
IEEE\ Std\ 1003.1-2001 and reduce the temptation to standardize prematurely
|
|
on semantics that are not yet widely
|
|
implemented or understood.
|
|
.LP
|
|
Examples of possible additional mutex attributes that have been discussed
|
|
are \fIspin_only\fP, \fIlimited_spin\fP,
|
|
\fIno_spin\fP, \fIrecursive\fP, and \fImetered\fP. (To explain what
|
|
the latter attributes might mean: recursive mutexes would
|
|
allow for multiple re-locking by the current owner; metered mutexes
|
|
would transparently keep records of queue length, wait time,
|
|
and so on.) Since there is not yet wide agreement on the usefulness
|
|
of these resulting from shared implementation and usage
|
|
experience, they are not yet specified in this volume of IEEE\ Std\ 1003.1-2001.
|
|
Mutex attributes objects, however, make it
|
|
possible to test out these concepts for possible standardization at
|
|
a later time.
|
|
.SS Mutex Attributes and Performance
|
|
.LP
|
|
Care has been taken to ensure that the default values of the mutex
|
|
attributes have been defined such that mutexes initialized
|
|
with the defaults have simple enough semantics so that the locking
|
|
and unlocking can be done with the equivalent of a test-and-set
|
|
instruction (plus possibly a few other basic instructions).
|
|
.LP
|
|
There is at least one implementation method that can be used to reduce
|
|
the cost of testing at lock-time if a mutex has
|
|
non-default attributes. One such method that an implementation can
|
|
employ (and this can be made fully transparent to fully
|
|
conforming POSIX applications) is to secretly pre-lock any mutexes
|
|
that are initialized to non-default attributes. Any later
|
|
attempt to lock such a mutex causes the implementation to branch to
|
|
the "slow path" as if the mutex were unavailable; then, on
|
|
the slow path, the implementation can do the "real work" to lock a
|
|
non-default mutex. The underlying unlock operation is more
|
|
complicated since the implementation never really wants to release
|
|
the pre-lock on this kind of mutex. This illustrates that,
|
|
depending on the hardware, there may be certain optimizations that
|
|
can be used so that whatever mutex attributes are considered
|
|
"most frequently used" can be processed most efficiently.
|
|
.SS Process Shared Memory and Synchronization
|
|
.LP
|
|
The existence of memory mapping functions in this volume of IEEE\ Std\ 1003.1-2001
|
|
leads to the possibility that an
|
|
application may allocate the synchronization objects from this section
|
|
in memory that is accessed by multiple processes (and
|
|
therefore, by threads of multiple processes).
|
|
.LP
|
|
In order to permit such usage, while at the same time keeping the
|
|
usual case (that is, usage within a single process) efficient,
|
|
a \fIprocess-shared\fP option has been defined.
|
|
.LP
|
|
If an implementation supports the _POSIX_THREAD_PROCESS_SHARED option,
|
|
then the \fIprocess-shared\fP attribute can be used to
|
|
indicate that mutexes or condition variables may be accessed by threads
|
|
of multiple processes.
|
|
.LP
|
|
The default setting of PTHREAD_PROCESS_PRIVATE has been chosen for
|
|
the \fIprocess-shared\fP attribute so that the most
|
|
efficient forms of these synchronization objects are created by default.
|
|
.LP
|
|
Synchronization variables that are initialized with the PTHREAD_PROCESS_PRIVATE
|
|
\fIprocess-shared\fP attribute may only be
|
|
operated on by threads in the process that initialized them. Synchronization
|
|
variables that are initialized with the
|
|
PTHREAD_PROCESS_SHARED \fIprocess-shared\fP attribute may be operated
|
|
on by any thread in any process that has access to it. In
|
|
particular, these processes may exist beyond the lifetime of the initializing
|
|
process. For example, the following code implements a
|
|
simple counting semaphore in a mapped file that may be used by many
|
|
processes.
|
|
.sp
|
|
.RS
|
|
.nf
|
|
|
|
\fB/* sem.h */
|
|
struct semaphore {
|
|
pthread_mutex_t lock;
|
|
pthread_cond_t nonzero;
|
|
unsigned count;
|
|
};
|
|
typedef struct semaphore semaphore_t;
|
|
.sp
|
|
|
|
semaphore_t *semaphore_create(char *semaphore_name);
|
|
semaphore_t *semaphore_open(char *semaphore_name);
|
|
void semaphore_post(semaphore_t *semap);
|
|
void semaphore_wait(semaphore_t *semap);
|
|
void semaphore_close(semaphore_t *semap);
|
|
.sp
|
|
|
|
/* sem.c */
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/mman.h>
|
|
#include <fcntl.h>
|
|
#include <pthread.h>
|
|
#include "sem.h"
|
|
.sp
|
|
|
|
semaphore_t *
|
|
semaphore_create(char *semaphore_name)
|
|
{
|
|
int fd;
|
|
semaphore_t *semap;
|
|
pthread_mutexattr_t psharedm;
|
|
pthread_condattr_t psharedc;
|
|
.sp
|
|
|
|
fd = open(semaphore_name, O_RDWR | O_CREAT | O_EXCL, 0666);
|
|
if (fd < 0)
|
|
return (NULL);
|
|
(void) ftruncate(fd, sizeof(semaphore_t));
|
|
(void) pthread_mutexattr_init(&psharedm);
|
|
(void) pthread_mutexattr_setpshared(&psharedm,
|
|
PTHREAD_PROCESS_SHARED);
|
|
(void) pthread_condattr_init(&psharedc);
|
|
(void) pthread_condattr_setpshared(&psharedc,
|
|
PTHREAD_PROCESS_SHARED);
|
|
semap = (semaphore_t *) mmap(NULL, sizeof(semaphore_t),
|
|
PROT_READ | PROT_WRITE, MAP_SHARED,
|
|
fd, 0);
|
|
close (fd);
|
|
(void) pthread_mutex_init(&semap->lock, &psharedm);
|
|
(void) pthread_cond_init(&semap->nonzero, &psharedc);
|
|
semap->count = 0;
|
|
return (semap);
|
|
}
|
|
.sp
|
|
|
|
semaphore_t *
|
|
semaphore_open(char *semaphore_name)
|
|
{
|
|
int fd;
|
|
semaphore_t *semap;
|
|
.sp
|
|
|
|
fd = open(semaphore_name, O_RDWR, 0666);
|
|
if (fd < 0)
|
|
return (NULL);
|
|
semap = (semaphore_t *) mmap(NULL, sizeof(semaphore_t),
|
|
PROT_READ | PROT_WRITE, MAP_SHARED,
|
|
fd, 0);
|
|
close (fd);
|
|
return (semap);
|
|
}
|
|
.sp
|
|
|
|
void
|
|
semaphore_post(semaphore_t *semap)
|
|
{
|
|
pthread_mutex_lock(&semap->lock);
|
|
if (semap->count == 0)
|
|
pthread_cond_signal(&semapx->nonzero);
|
|
semap->count++;
|
|
pthread_mutex_unlock(&semap->lock);
|
|
}
|
|
.sp
|
|
|
|
void
|
|
semaphore_wait(semaphore_t *semap)
|
|
{
|
|
pthread_mutex_lock(&semap->lock);
|
|
while (semap->count == 0)
|
|
pthread_cond_wait(&semap->nonzero, &semap->lock);
|
|
semap->count--;
|
|
pthread_mutex_unlock(&semap->lock);
|
|
}
|
|
.sp
|
|
|
|
void
|
|
semaphore_close(semaphore_t *semap)
|
|
{
|
|
munmap((void *) semap, sizeof(semaphore_t));
|
|
}
|
|
\fP
|
|
.fi
|
|
.RE
|
|
.LP
|
|
The following code is for three separate processes that create, post,
|
|
and wait on a semaphore in the file \fB/tmp/semaphore\fP.
|
|
Once the file is created, the post and wait programs increment and
|
|
decrement the counting semaphore (waiting and waking as
|
|
required) even though they did not initialize the semaphore.
|
|
.sp
|
|
.RS
|
|
.nf
|
|
|
|
\fB/* create.c */
|
|
#include "pthread.h"
|
|
#include "sem.h"
|
|
.sp
|
|
|
|
int
|
|
main()
|
|
{
|
|
semaphore_t *semap;
|
|
.sp
|
|
|
|
semap = semaphore_create("/tmp/semaphore");
|
|
if (semap == NULL)
|
|
exit(1);
|
|
semaphore_close(semap);
|
|
return (0);
|
|
}
|
|
.sp
|
|
|
|
/* post */
|
|
#include "pthread.h"
|
|
#include "sem.h"
|
|
.sp
|
|
|
|
int
|
|
main()
|
|
{
|
|
semaphore_t *semap;
|
|
.sp
|
|
|
|
semap = semaphore_open("/tmp/semaphore");
|
|
if (semap == NULL)
|
|
exit(1);
|
|
semaphore_post(semap);
|
|
semaphore_close(semap);
|
|
return (0);
|
|
}
|
|
.sp
|
|
|
|
/* wait */
|
|
#include "pthread.h"
|
|
#include "sem.h"
|
|
.sp
|
|
|
|
int
|
|
main()
|
|
{
|
|
semaphore_t *semap;
|
|
.sp
|
|
|
|
semap = semaphore_open("/tmp/semaphore");
|
|
if (semap == NULL)
|
|
exit(1);
|
|
semaphore_wait(semap);
|
|
semaphore_close(semap);
|
|
return (0);
|
|
}
|
|
\fP
|
|
.fi
|
|
.RE
|
|
.SH FUTURE DIRECTIONS
|
|
.LP
|
|
None.
|
|
.SH SEE ALSO
|
|
.LP
|
|
\fIpthread_cond_destroy\fP() , \fIpthread_create\fP() , \fIpthread_mutex_destroy\fP()
|
|
, pthread_mutexattr_destroy , the Base Definitions volume of IEEE\ Std\ 1003.1-2001,
|
|
\fI<pthread.h>\fP
|
|
.SH COPYRIGHT
|
|
Portions of this text are reprinted and reproduced in electronic form
|
|
from IEEE Std 1003.1, 2003 Edition, Standard for Information Technology
|
|
-- Portable Operating System Interface (POSIX), The Open Group Base
|
|
Specifications Issue 6, Copyright (C) 2001-2003 by the Institute of
|
|
Electrical and Electronics Engineers, Inc and The Open Group. In the
|
|
event of any discrepancy between this version and the original IEEE and
|
|
The Open Group Standard, the original IEEE and The Open Group Standard
|
|
is the referee document. The original Standard can be obtained online at
|
|
http://www.opengroup.org/unix/online.html .
|