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_detach(uv_thread_t* tid) 82 83 Detaches a thread. Detached threads automatically release their 84 resources upon termination, eliminating the need for the application to 85 call `uv_thread_join`. 86 87 .. versionadded:: 1.50.0 88 89.. c:function:: int uv_thread_create_ex(uv_thread_t* tid, const uv_thread_options_t* params, uv_thread_cb entry, void* arg) 90 91 Like :c:func:`uv_thread_create`, but additionally specifies options for creating a new thread. 92 93 If `UV_THREAD_HAS_STACK_SIZE` is set, `stack_size` specifies a stack size for the new thread. 94 `0` indicates that the default value should be used, i.e. behaves as if the flag was not set. 95 Other values will be rounded up to the nearest page boundary. 96 97 .. versionadded:: 1.26.0 98 99.. c:function:: int uv_thread_setaffinity(uv_thread_t* tid, char* cpumask, char* oldmask, size_t mask_size) 100 101 Sets the specified thread's affinity to cpumask, which is specified in 102 bytes. Optionally returning the previous affinity setting in oldmask. 103 On Unix, uses :man:`pthread_getaffinity_np(3)` to get the affinity setting 104 and maps the cpu_set_t to bytes in oldmask. Then maps the bytes in cpumask 105 to a cpu_set_t and uses :man:`pthread_setaffinity_np(3)`. On Windows, maps 106 the bytes in cpumask to a bitmask and uses SetThreadAffinityMask() which 107 returns the previous affinity setting. 108 109 The mask_size specifies the number of entries (bytes) in cpumask / oldmask, 110 and must be greater-than-or-equal-to :c:func:`uv_cpumask_size`. 111 112 .. note:: 113 Thread affinity setting is not atomic on Windows. Unsupported on macOS. 114 115 .. versionadded:: 1.45.0 116 117.. c:function:: int uv_thread_getaffinity(uv_thread_t* tid, char* cpumask, size_t mask_size) 118 119 Gets the specified thread's affinity setting. On Unix, this maps the 120 cpu_set_t returned by :man:`pthread_getaffinity_np(3)` to bytes in cpumask. 121 122 The mask_size specifies the number of entries (bytes) in cpumask, 123 and must be greater-than-or-equal-to :c:func:`uv_cpumask_size`. 124 125 .. note:: 126 Thread affinity getting is not atomic on Windows. Unsupported on macOS. 127 128 .. versionadded:: 1.45.0 129 130.. c:function:: int uv_thread_getcpu(void) 131 132 Gets the CPU number on which the calling thread is running. 133 134 .. note:: 135 Currently only implemented on Windows, Linux and FreeBSD. 136 137 .. versionadded:: 1.45.0 138 139.. c:function:: uv_thread_t uv_thread_self(void) 140.. c:function:: int uv_thread_join(uv_thread_t *tid) 141.. c:function:: int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) 142 143.. c:function:: int uv_thread_setname(const char* name) 144 145 Sets the name of the current thread. Different platforms define different limits on the max number of characters 146 a thread name can be: Linux, IBM i (16), macOS (64), Windows (32767), and NetBSD (32), etc. `uv_thread_setname()` 147 will truncate it in case `name` is larger than the limit of the platform. 148 149 .. versionadded:: 1.50.0 150 151.. c:function:: int uv_thread_getname(uv_thread_t* tid, char* name, size_t* size) 152 153 Gets the name of the thread specified by `tid`. The thread name is copied, with the trailing NUL, into the buffer 154 pointed to by `name`. The `size` parameter specifies the size of the buffer pointed to by `name`. 155 The buffer should be large enough to hold the name of the thread plus the trailing NUL, or it will be truncated to fit 156 with the trailing NUL. 157 158 .. versionadded:: 1.50.0 159 160.. c:function:: int uv_thread_setpriority(uv_thread_t tid, int priority) 161 If the function succeeds, the return value is 0. 162 If the function fails, the return value is less than zero. 163 Sets the scheduling priority of the thread specified by tid. It requires elevated 164 privilege to set specific priorities on some platforms. 165 The priority can be set to the following constants. UV_THREAD_PRIORITY_HIGHEST, 166 UV_THREAD_PRIORITY_ABOVE_NORMAL, UV_THREAD_PRIORITY_NORMAL, 167 UV_THREAD_PRIORITY_BELOW_NORMAL, UV_THREAD_PRIORITY_LOWEST. 168.. c:function:: int uv_thread_getpriority(uv_thread_t tid, int* priority) 169 If the function succeeds, the return value is 0. 170 If the function fails, the return value is less than zero. 171 Retrieves the scheduling priority of the thread specified by tid. The value in the 172 output parameter priority is platform dependent. 173 For Linux, when schedule policy is SCHED_OTHER (default), priority is 0. 174 175Thread-local storage 176^^^^^^^^^^^^^^^^^^^^ 177 178.. note:: 179 The total thread-local storage size may be limited. That is, it may not be possible to 180 create many TLS keys. 181 182.. c:function:: int uv_key_create(uv_key_t* key) 183.. c:function:: void uv_key_delete(uv_key_t* key) 184.. c:function:: void* uv_key_get(uv_key_t* key) 185.. c:function:: void uv_key_set(uv_key_t* key, void* value) 186 187Once-only initialization 188^^^^^^^^^^^^^^^^^^^^^^^^ 189 190Runs a function once and only once. Concurrent calls to :c:func:`uv_once` with the 191same guard will block all callers except one (it's unspecified which one). 192The guard should be initialized statically with the UV_ONCE_INIT macro. 193 194.. c:function:: void uv_once(uv_once_t* guard, void (*callback)(void)) 195 196Mutex locks 197^^^^^^^^^^^ 198 199Functions return 0 on success or an error code < 0 (unless the 200return type is void, of course). 201 202.. c:function:: int uv_mutex_init(uv_mutex_t* handle) 203.. c:function:: int uv_mutex_init_recursive(uv_mutex_t* handle) 204.. c:function:: void uv_mutex_destroy(uv_mutex_t* handle) 205.. c:function:: void uv_mutex_lock(uv_mutex_t* handle) 206.. c:function:: int uv_mutex_trylock(uv_mutex_t* handle) 207.. c:function:: void uv_mutex_unlock(uv_mutex_t* handle) 208 209Read-write locks 210^^^^^^^^^^^^^^^^ 211 212Functions return 0 on success or an error code < 0 (unless the 213return type is void, of course). 214 215.. c:function:: int uv_rwlock_init(uv_rwlock_t* rwlock) 216.. c:function:: void uv_rwlock_destroy(uv_rwlock_t* rwlock) 217.. c:function:: void uv_rwlock_rdlock(uv_rwlock_t* rwlock) 218.. c:function:: int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) 219.. c:function:: void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) 220.. c:function:: void uv_rwlock_wrlock(uv_rwlock_t* rwlock) 221.. c:function:: int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) 222.. c:function:: void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) 223 224Semaphores 225^^^^^^^^^^ 226 227Functions return 0 on success or an error code < 0 (unless the 228return type is void, of course). 229 230.. c:function:: int uv_sem_init(uv_sem_t* sem, unsigned int value) 231.. c:function:: void uv_sem_destroy(uv_sem_t* sem) 232.. c:function:: void uv_sem_post(uv_sem_t* sem) 233.. c:function:: void uv_sem_wait(uv_sem_t* sem) 234.. c:function:: int uv_sem_trywait(uv_sem_t* sem) 235 236Conditions 237^^^^^^^^^^ 238 239Functions return 0 on success or an error code < 0 (unless the 240return type is void, of course). 241 242.. note:: 243 1. Callers should be prepared to deal with spurious wakeups on :c:func:`uv_cond_wait` 244 and :c:func:`uv_cond_timedwait`. 245 2. The timeout parameter for :c:func:`uv_cond_timedwait` is relative to the time 246 at which function is called. 247 3. On z/OS, the timeout parameter for :c:func:`uv_cond_timedwait` is converted to an 248 absolute system time at which the wait expires. If the current system clock time 249 passes the absolute time calculated before the condition is signaled, an ETIMEDOUT 250 error results. After the wait begins, the wait time is not affected by changes 251 to the system clock. 252 253.. c:function:: int uv_cond_init(uv_cond_t* cond) 254.. c:function:: void uv_cond_destroy(uv_cond_t* cond) 255.. c:function:: void uv_cond_signal(uv_cond_t* cond) 256.. c:function:: void uv_cond_broadcast(uv_cond_t* cond) 257.. c:function:: void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) 258.. c:function:: int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) 259 260Barriers 261^^^^^^^^ 262 263Functions return 0 on success or an error code < 0 (unless the 264return type is void, of course). 265 266.. note:: 267 :c:func:`uv_barrier_wait` returns a value > 0 to an arbitrarily chosen "serializer" thread 268 to facilitate cleanup, i.e. 269 270 :: 271 272 if (uv_barrier_wait(&barrier) > 0) 273 uv_barrier_destroy(&barrier); 274 275.. c:function:: int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) 276.. c:function:: void uv_barrier_destroy(uv_barrier_t* barrier) 277.. c:function:: int uv_barrier_wait(uv_barrier_t* barrier) 278