Threads

Overview

Thread support is provided through the standard <threads.h> header. Threads are referenced via a thrd_t opaque handle type. Two principal function interfaces are used to start a thread and wait for it to terminate respectively:

typedef int (*thrd_start_t)(void*);
int thrd_create(thrd_t*, thrd_start_t, void*);
int thrd_join(thrd_t, int*);

Initialization

The call_once function uses a once_flag object to ensure that a function is called exactly once. Any other threads reaching this point of execution wait until the call_once callback completes.

void call_once(once_flag *flag, void (*func)(void));

Storage

Keyword _Thread_local is used for defining variables in TLS. This should be prefered when a thread-specific object can be initialized at compile time.

TSD is referred to as thread-specific storage (TSS) in C but operates in much the same way. Each object within TSS has an associated key. Once a key is set, upon thread creation, the value associated with all keys is initialized to a null pointer value in the new thread.

int tss_create(tss_t *key, tss_dtor_t dtor);
void *tss_get(tss_t key);
int tss_set(tss_t key, void *val);

Mutexes

The C standard provides mutex support with the mtx_t type. An object of this type can be initialized using a valid combination of the following flags:

  1. mtx_plain to create a mutex that does not support timeout.
  2. mtx_timed to create a mutex that supports timeout.
  3. mtx_recursive to create a mutex that supports recursive locking.
void mtx_init(mtx_t *mtx, int type);
void mtx_destroy(mtx_t *mtx);
int mtx_lock(mtx_t *mtx);
int mtx_unlock(mtx_t *mtx);

Condition Variables

A condition variable is a synchronization primitive used alongside a mutex to block one or more threads until another thread notifies the variable.

A condition variable is represented with type cnd_t. cnd_wait (and its variants) must be invoked while its corresponding mutex is locked.

int cnd_init(cnd_t *cond);
int cnd_destroy(cnd_t *cond);
int cnd_wait(cnd_t *cond, mtx_t *mtx);
int cnd_signal(cnd_t *cond);
int cnd_broadcast(cnd_t *cond);
Powered by Forestry.md