Name | Description | Notes | Source | Availability | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|
__STDC_ |
Indicator of lack of standard threading | L | ? | M | Predefined | C11 |
Name | Description | Notes | Source | Availability | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|
call_ |
Ensure that a function has been invoked exactly once | ? | (·) | <threads.h> |
C11 | ||||||
cnd_ |
Signal to all threads on a condition variable | ? | (·) | <threads.h> |
C11 | ||||||
cnd_ |
Destroy a condition variable | ? | (·) | <threads.h> |
C11 | ||||||
cnd_ |
Initialize a condition variable | ? | (·) | <threads.h> |
C11 | ||||||
cnd_ |
Signal to a thread on a condition variable | ? | (·) | <threads.h> |
C11 | ||||||
cnd_t |
Condition-variable type | ? | T | <threads.h> |
C11 | ||||||
cnd_ |
Wait on a condition variable for a limited time | ? | (·) | <threads.h> |
C11 | ||||||
cnd_ |
Wait on a condition variable | ? | (·) | <threads.h> |
C11 | ||||||
mtx_ |
Destroy a mutex | ? | (·) | <threads.h> |
C11 | ||||||
mtx_ |
Initialize a mutex | ? | (·) | <threads.h> |
C11 | ||||||
mtx_ |
Lock a mutex | ? | (·) | <threads.h> |
C11 | ||||||
mtx_ |
Type of non-recursive, non-timeout mutex | ? | <threads.h> |
C11 | |||||||
mtx_ |
Type of mutex supporting recursion | ? | <threads.h> |
C11 | |||||||
mtx_t |
Mutex-identifier type | ? | T | <threads.h> |
C11 | ||||||
mtx_ |
Type of mutex supporting timeout | ? | <threads.h> |
C11 | |||||||
mtx_ |
Try for some time to lock a mutex | ? | (·) | <threads.h> |
C11 | ||||||
mtx_ |
Try to lock a mutex | ? | (·) | <threads.h> |
C11 | ||||||
mtx_ |
Unlock a mutex | ? | (·) | <threads.h> |
C11 | ||||||
ONCE_ |
Initializer for once_ |
? | M | <threads.h> |
C11 | ||||||
once_ |
Flag type to detect exactly one invocation | ? | T | <threads.h> |
C11 | ||||||
TSS_ |
Maximum number of destructor invocations | ? | M | <threads.h> |
C11 | ||||||
thrd_ |
Indicator of blocked thread operation | ? | <threads.h> |
C11 | |||||||
thrd_ |
Create and start a thread | ? | (·) | <threads.h> |
C11 | ||||||
thrd_ |
Identify the current thread | ? | (·) | <threads.h> |
C11 | ||||||
thrd_ |
Dispose of thread resources | ? | (·) | <threads.h> |
C11 | ||||||
thrd_ |
Test whether two thread identifiers refer to the same thread | ? | (·) | <threads.h> |
C11 | ||||||
thrd_ |
Indicator of errant thread operation | ? | <threads.h> |
C11 | |||||||
thrd_ |
Terminate the current thread | (·) | <threads.h> |
C11 | |||||||
thrd_ |
Await thread termination | ? | (·) | <threads.h> |
C11 | ||||||
thrd_ |
Indicator of insufficient memory to carry out thread operation | ? | <threads.h> |
C11 | |||||||
thrd_ |
Suspend current thread | ? | (·) | <threads.h> |
C11 | ||||||
thrd_ |
Thread action type | ? | T | <threads.h> |
C11 | ||||||
thrd_ |
Indicator of successful thread operation | ? | <threads.h> |
C11 | |||||||
thrd_t |
Thread-identifier type | ? | T | <threads.h> |
C11 | ||||||
thrd_ |
Indicator of time-limited thread operation | ? | <threads.h> |
C11 | |||||||
thrd_ |
Allow other threads to run | ? | (·) | <threads.h> |
C11 | ||||||
thread_ |
Storage class for thread-local variables | ? | M | S | <threads.h> |
C11 | |||||
tss_ |
Create thread-specific storage | ? | (·) | <threads.h> |
C11 | ||||||
tss_ |
Destroy thread-specific storage | ? | (·) | <threads.h> |
C11 | ||||||
tss_ |
Destructor type for thread-specific storage | ? | T | <threads.h> |
C11 | ||||||
tss_ |
Read thread-specific storage | ? | (·) | <threads.h> |
C11 | ||||||
tss_ |
Write thread-specific storage | ? | (·) | <threads.h> |
C11 | ||||||
tss_t |
Thread-specific storage identifier type | ? | T | <threads.h> |
C11 |
This header is available in C11.
Names matching ^thrd_[a-z]
might be added to <threads.h>
.
Many computing environments support concurrent execution within a single process, allowing them to take advantage of multiple processor cores. Each execution through a program is called a thread.
Multithreading is a natural way to exploit multiple processors, but it has complications. Threads of the same process share the same process state, including all static and dynamic objects, so it's easy for two threads to mistakenly manipulate a complex structure in such a way that it is left in an internally inconsistent state. Avoiding this problem requires concepts such as mutual exclusion and condition variables. Thread-local objects are safe, because such an object is actually a collection of objects, each one being accessible from only one thread. Automatic objects are safe, as long as they are not exposed by storing their addresses in static or dynamic structures.
C11 specifies a threading library
in the form of a header <threads.h>
. Not all
implementations have to include it, so you can test for its
availability with an idiom such as:
#if __STDC_VERSION__ > 201112 && __STDC_NO_ != 1 #includeTHREADS__ <threads.h>
#else #error "Threading unavailable" #endif
<threads.h>
defines
thrd_t
as a
thread identifier. It also defines a number of return codes
to indicate the outcome of attempting a thread-related
operation. Many functions return thrd_
to indicate a successful operation.
thrd_
is returned to indicate a lack
of memory. thrd_
indicates a failed operation. thrd_
indicates that a related operation would have blocked under
the same conditions. thrd_
indicates that an operation timed out.
Function | Return value | ||||
---|---|---|---|---|---|
thrd_ |
thrd_ |
thrd_ |
thrd_ |
thrd_ |
|
thrd_ |
✔ | ✔ | ✔ | ||
thrd_ |
✔ | ✔ | |||
thrd_ |
✔ | ✔ | |||
mtx_ |
✔ | ✔ | |||
mtx_ |
✔ | ✔ | |||
mtx_ |
✔ | ✔ | ✔ | ||
mtx_ |
✔ | ✔ | ✔ | ||
mtx_ |
✔ | ✔ | |||
cnd_ |
✔ | ✔ | ✔ | ||
cnd_ |
✔ | ✔ | |||
cnd_ |
✔ | ✔ | ✔ | ||
cnd_ |
✔ | ✔ | |||
cnd_ |
✔ | ✔ | |||
tss_ |
✔ | ✔ | |||
tss_ |
✔ | ✔ |
#include<threads.h>
typedef void (*thrd_start_t )(void *); int thrd_create (thrd_t *thp, thrd_start_t func, void *arg); int thrd_detach (thrd_t th);
thrd_
creates a new thread that will execute (*func)(arg)
. If successful, it assigns the new
thread identifier to *thp
, and returns
thrd_
.
If there is insufficient memory to start a new thread, it
returns
thrd_
. If it fails for any other
reason, it returns thrd_
.
If the call to (*func)(arg)
returns, it behaves as if the thread then calls thrd_
.
thrd_
tells the environment to deallocate resources for the thread
identified by th
when it terminates.
It returns thrd_
on success, and thrd_
on failure.
#include<threads.h>
thrd_t thrd_current (void); int thrd_equal (thrd_t a, thrd_t b);
thrd_
returns the identifier of the thread that called it.
thrd_
returns non-zero if the two
arguments a
and b
identify the same thread.
#include<threads.h>
_Noreturn void thrd_exit (int st); int thrd_join (thrd_t th, int *stp);
If a thread th
calls thrd_
,
the thread terminates. If another thread calls thrd_
to join with the thread th
, it will
block until that thread terminates. The function then returns
thrd_
.
The argument st
becomes the exit
status of the thread, and is assigned to *stp
for all threads waiting to join it.
stp
can be NULL
, indicating that the
calling thread does not require the exit status of
th
.
thrd_
returns thrd_
if the request to join a thread could not be honoured.
#include<threads.h>
void thrd_yield (void); int thrd_sleep (const struct timespec *dur, struct timespec *rem);
thrd_
gives other threads an opportunity to run even if the current
thread is occupying execution resources, such as a physical
processor. thrd_
makes the current thread wait for the duration specified by
*dur
. It then returns zero. If it is
interrupted by a signal that is not being ignored with
SIG_
, it will return
prematurely with -1
, having assigned
the remaining time to *rem
if
rem
is not null. If it fails, it
returns some other negative value.