xref: /libuv/docs/src/threading.rst (revision e135dfe1)
1
2.. _threading:
3
4Threading and synchronization utilities
5=======================================
6
7libuv provides cross-platform implementations for multiple threading and
8synchronization primitives. The API largely follows the pthreads API.
9
10
11Data types
12----------
13
14.. c:type:: uv_thread_t
15
16    Thread data type.
17
18.. c:type:: void (*uv_thread_cb)(void* arg)
19
20    Callback that is invoked to initialize thread execution. `arg` is the same
21    value that was passed to :c:func:`uv_thread_create`.
22
23.. c:type:: uv_key_t
24
25    Thread-local key data type.
26
27.. c:type:: uv_once_t
28
29    Once-only initializer data type.
30
31.. c:type:: uv_mutex_t
32
33    Mutex data type.
34
35.. c:type:: uv_rwlock_t
36
37    Read-write lock data type.
38
39.. c:type:: uv_sem_t
40
41    Semaphore data type.
42
43.. c:type:: uv_cond_t
44
45    Condition data type.
46
47.. c:type:: uv_barrier_t
48
49    Barrier data type.
50
51
52API
53---
54
55Threads
56^^^^^^^
57
58.. c:type:: uv_thread_options_t
59
60    Options for spawning a new thread (passed to :c:func:`uv_thread_create_ex`).
61
62    ::
63
64        typedef struct uv_thread_options_s {
65          enum {
66            UV_THREAD_NO_FLAGS = 0x00,
67            UV_THREAD_HAS_STACK_SIZE = 0x01
68          } flags;
69          size_t stack_size;
70        } uv_thread_options_t;
71
72    More fields may be added to this struct at any time, so its exact
73    layout and size should not be relied upon.
74
75    .. versionadded:: 1.26.0
76
77.. c:function:: int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg)
78
79    .. versionchanged:: 1.4.1 returns a UV_E* error code on failure
80
81.. c:function:: int uv_thread_create_ex(uv_thread_t* tid, const uv_thread_options_t* params, uv_thread_cb entry, void* arg)
82
83    Like :c:func:`uv_thread_create`, but additionally specifies options for creating a new thread.
84
85    If `UV_THREAD_HAS_STACK_SIZE` is set, `stack_size` specifies a stack size for the new thread.
86    `0` indicates that the default value should be used, i.e. behaves as if the flag was not set.
87    Other values will be rounded up to the nearest page boundary.
88
89    .. versionadded:: 1.26.0
90
91.. c:function:: int uv_thread_setaffinity(uv_thread_t* tid, char* cpumask, char* oldmask, size_t mask_size)
92
93    Sets the specified thread's affinity to cpumask, which is specified in
94    bytes. Optionally returning the previous affinity setting in oldmask.
95    On Unix, uses :man:`pthread_getaffinity_np(3)` to get the affinity setting
96    and maps the cpu_set_t to bytes in oldmask. Then maps the bytes in cpumask
97    to a cpu_set_t and uses :man:`pthread_setaffinity_np(3)`. On Windows, maps
98    the bytes in cpumask to a bitmask and uses SetThreadAffinityMask() which
99    returns the previous affinity setting.
100
101    The mask_size specifies the number of entries (bytes) in cpumask / oldmask,
102    and must be greater-than-or-equal-to :c:func:`uv_cpumask_size`.
103
104    .. note::
105        Thread affinity setting is not atomic on Windows. Unsupported on macOS.
106
107    .. versionadded:: 1.45.0
108
109.. c:function:: int uv_thread_getaffinity(uv_thread_t* tid, char* cpumask, size_t mask_size)
110
111    Gets the specified thread's affinity setting. On Unix, this maps the
112    cpu_set_t returned by :man:`pthread_getaffinity_np(3)` to bytes in cpumask.
113
114    The mask_size specifies the number of entries (bytes) in cpumask,
115    and must be greater-than-or-equal-to :c:func:`uv_cpumask_size`.
116
117    .. note::
118        Thread affinity getting is not atomic on Windows. Unsupported on macOS.
119
120    .. versionadded:: 1.45.0
121
122.. c:function:: int uv_thread_getcpu(void)
123
124    Gets the CPU number on which the calling thread is running.
125
126    .. note::
127        Currently only implemented on Windows, Linux and FreeBSD.
128
129    .. versionadded:: 1.45.0
130
131.. c:function:: uv_thread_t uv_thread_self(void)
132.. c:function:: int uv_thread_join(uv_thread_t *tid)
133.. c:function:: int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2)
134
135.. c:function:: int uv_thread_setpriority(uv_thread_t tid, int priority)
136    If the function succeeds, the return value is 0.
137    If the function fails, the return value is less than zero.
138    Sets the scheduling priority of the thread specified by tid. It requires elevated
139    privilege to set specific priorities on some platforms.
140    The priority can be set to the following constants. UV_THREAD_PRIORITY_HIGHEST,
141    UV_THREAD_PRIORITY_ABOVE_NORMAL, UV_THREAD_PRIORITY_NORMAL,
142    UV_THREAD_PRIORITY_BELOW_NORMAL, UV_THREAD_PRIORITY_LOWEST.
143.. c:function:: int uv_thread_getpriority(uv_thread_t tid, int* priority)
144    If the function succeeds, the return value is 0.
145    If the function fails, the return value is less than zero.
146    Retrieves the scheduling priority of the thread specified by tid. The value in the
147    output parameter priority is platform dependent.
148    For Linux, when schedule policy is SCHED_OTHER (default), priority is 0.
149
150Thread-local storage
151^^^^^^^^^^^^^^^^^^^^
152
153.. note::
154    The total thread-local storage size may be limited. That is, it may not be possible to
155    create many TLS keys.
156
157.. c:function:: int uv_key_create(uv_key_t* key)
158.. c:function:: void uv_key_delete(uv_key_t* key)
159.. c:function:: void* uv_key_get(uv_key_t* key)
160.. c:function:: void uv_key_set(uv_key_t* key, void* value)
161
162Once-only initialization
163^^^^^^^^^^^^^^^^^^^^^^^^
164
165Runs a function once and only once. Concurrent calls to :c:func:`uv_once` with the
166same guard will block all callers except one (it's unspecified which one).
167The guard should be initialized statically with the UV_ONCE_INIT macro.
168
169.. c:function:: void uv_once(uv_once_t* guard, void (*callback)(void))
170
171Mutex locks
172^^^^^^^^^^^
173
174Functions return 0 on success or an error code < 0 (unless the
175return type is void, of course).
176
177.. c:function:: int uv_mutex_init(uv_mutex_t* handle)
178.. c:function:: int uv_mutex_init_recursive(uv_mutex_t* handle)
179.. c:function:: void uv_mutex_destroy(uv_mutex_t* handle)
180.. c:function:: void uv_mutex_lock(uv_mutex_t* handle)
181.. c:function:: int uv_mutex_trylock(uv_mutex_t* handle)
182.. c:function:: void uv_mutex_unlock(uv_mutex_t* handle)
183
184Read-write locks
185^^^^^^^^^^^^^^^^
186
187Functions return 0 on success or an error code < 0 (unless the
188return type is void, of course).
189
190.. c:function:: int uv_rwlock_init(uv_rwlock_t* rwlock)
191.. c:function:: void uv_rwlock_destroy(uv_rwlock_t* rwlock)
192.. c:function:: void uv_rwlock_rdlock(uv_rwlock_t* rwlock)
193.. c:function:: int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock)
194.. c:function:: void uv_rwlock_rdunlock(uv_rwlock_t* rwlock)
195.. c:function:: void uv_rwlock_wrlock(uv_rwlock_t* rwlock)
196.. c:function:: int uv_rwlock_trywrlock(uv_rwlock_t* rwlock)
197.. c:function:: void uv_rwlock_wrunlock(uv_rwlock_t* rwlock)
198
199Semaphores
200^^^^^^^^^^
201
202Functions return 0 on success or an error code < 0 (unless the
203return type is void, of course).
204
205.. c:function:: int uv_sem_init(uv_sem_t* sem, unsigned int value)
206.. c:function:: void uv_sem_destroy(uv_sem_t* sem)
207.. c:function:: void uv_sem_post(uv_sem_t* sem)
208.. c:function:: void uv_sem_wait(uv_sem_t* sem)
209.. c:function:: int uv_sem_trywait(uv_sem_t* sem)
210
211Conditions
212^^^^^^^^^^
213
214Functions return 0 on success or an error code < 0 (unless the
215return type is void, of course).
216
217.. note::
218    1. Callers should be prepared to deal with spurious wakeups on :c:func:`uv_cond_wait`
219       and :c:func:`uv_cond_timedwait`.
220    2. The timeout parameter for :c:func:`uv_cond_timedwait` is relative to the time
221       at which function is called.
222    3. On z/OS, the timeout parameter for :c:func:`uv_cond_timedwait` is converted to an
223       absolute system time at which the wait expires. If the current system clock time
224       passes the absolute time calculated before the condition is signaled, an ETIMEDOUT
225       error results. After the wait begins, the wait time is not affected by changes
226       to the system clock.
227
228.. c:function:: int uv_cond_init(uv_cond_t* cond)
229.. c:function:: void uv_cond_destroy(uv_cond_t* cond)
230.. c:function:: void uv_cond_signal(uv_cond_t* cond)
231.. c:function:: void uv_cond_broadcast(uv_cond_t* cond)
232.. c:function:: void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex)
233.. c:function:: int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout)
234
235Barriers
236^^^^^^^^
237
238Functions return 0 on success or an error code < 0 (unless the
239return type is void, of course).
240
241.. note::
242    :c:func:`uv_barrier_wait` returns a value > 0 to an arbitrarily chosen "serializer" thread
243    to facilitate cleanup, i.e.
244
245    ::
246
247        if (uv_barrier_wait(&barrier) > 0)
248            uv_barrier_destroy(&barrier);
249
250.. c:function:: int uv_barrier_init(uv_barrier_t* barrier, unsigned int count)
251.. c:function:: void uv_barrier_destroy(uv_barrier_t* barrier)
252.. c:function:: int uv_barrier_wait(uv_barrier_t* barrier)
253