スレッドと同期のユーティリティー

libuvは、複数のスレッド処理・同期プリミティブについて、プラットフォーム間で使える実装を提供します。APIはおおむねpthreads APIに従っています。

データ型

type uv_thread_t

スレッドのデータ型です。

typedef void (*uv_thread_cb)(void *arg)

スレッドの実行を開始するときに呼び出すコールバックです。argには、次の関数へ渡したものと同じ値が入ります: uv_thread_create()。

type uv_key_t

スレッドローカルキーのデータ型です。

type uv_once_t

1回だけ行う初期化のデータ型です。

type uv_mutex_t

ミューテックスのデータ型です。

type uv_rwlock_t

読み書きロックのデータ型です。

type uv_sem_t

セマフォのデータ型です。

type uv_cond_t

条件変数のデータ型です。

type uv_barrier_t

バリアのデータ型です。

API

スレッド

type uv_thread_options_t

新しいスレッドを起動するためのオプションです。次の関数へ渡します: uv_thread_create_ex()。

typedef struct uv_thread_options_s {
  enum {
    UV_THREAD_NO_FLAGS = 0x00,
    UV_THREAD_HAS_STACK_SIZE = 0x01
  } flags;
  size_t stack_size;
} uv_thread_options_t;

この構造体にはいつでもフィールドを追加する可能性があるため、正確なレイアウトやサイズに依存しないでください。

バージョン1.26.0で追加。

int uv_thread_create(uv_thread_t *tid, uv_thread_cb entry, void *arg)

バージョン1.4.1での変更: 失敗時にUV_E*エラーコードを返すようになりました。

int uv_thread_detach(uv_thread_t *tid)

スレッドをデタッチします。デタッチしたスレッドは終了時にリソースを自動的に解放するため、アプリケーションが次の関数を呼び出す必要はありません: uv_thread_join。

バージョン1.50.0で追加。

int uv_thread_create_ex(uv_thread_t *tid, const uv_thread_options_t *params, uv_thread_cb entry, void *arg)

次の関数、uv_thread_create()と同様ですが、新しいスレッドを作成するオプションも指定します。

次のフラグ、UV_THREAD_HAS_STACK_SIZEを設定すると、stack_sizeが新しいスレッドのスタックサイズを指定します。0はデフォルト値を使うことを示し、フラグを設定しなかった場合と同じ動作になります。それ以外の値は、次のページ境界まで切り上げます。

バージョン1.26.0で追加。

int uv_thread_setaffinity(uv_thread_t *tid, char *cpumask, char *oldmask, size_t mask_size)

指定したスレッドのアフィニティーを、バイト単位で指定するcpumaskに設定します。必要に応じて以前の設定をoldmaskに返します。Unixでは、次の関数を使って設定を取得します: pthread_getaffinity_np(3)。cpu_set_tをoldmaskのバイト列へ変換します。続いて、cpumaskのバイト列をcpu_set_tへ変換し、次の関数を使います: pthread_setaffinity_np(3)。Windowsでは、cpumaskのバイト列をビットマスクへ変換し、以前の設定を返すSetThreadAffinityMask()を使います。

mask_sizeはcpumaskとoldmaskの要素数(バイト数)を指定します。次の関数の値以上である必要があります: uv_cpumask_size()。

注記

Windowsでは、スレッドアフィニティーの設定はアトミックではありません。macOSではサポートしていません。

バージョン1.45.0で追加。

int uv_thread_getaffinity(uv_thread_t *tid, char *cpumask, size_t mask_size)

指定したスレッドのアフィニティー設定を取得します。Unixでは、次の関数、pthread_getaffinity_np(3)が返したcpu_set_tを、cpumaskのバイト列へ変換します。

mask_sizeはcpumaskの要素数(バイト数)を指定します。次の関数の値以上である必要があります: uv_cpumask_size()。

注記

Windowsでは、スレッドアフィニティーの取得はアトミックではありません。macOSではサポートしていません。

バージョン1.45.0で追加。

int uv_thread_getcpu(void)

呼び出し元スレッドが実行されているCPUの番号を取得します。

注記

現在、Windows、Linux、FreeBSDだけに実装しています。

バージョン1.45.0で追加。

uv_thread_t uv_thread_self(void)
int uv_thread_join(uv_thread_t *tid)
int uv_thread_equal(const uv_thread_t *t1, const uv_thread_t *t2)
int uv_thread_setname(const char *name)

現在のスレッドの名前を設定します。名前の最大文字数はプラットフォームによって異なり、LinuxとIBM iは16、macOSは64、Windowsは32767、NetBSDは32などです。次の関数、uv_thread_setname()は、nameがそのプラットフォームの上限より長い場合に切り詰めます。

Windows Server 2016ではサポートせず、次のエラーを返します: UV_ENOSYS。

バージョン1.50.0で追加。

int uv_thread_getname(uv_thread_t *tid, char *name, size_t *size)

次の引数で指定したスレッドの名前を取得します: tid。スレッド名を、末尾のNULを含めて、次の引数が指すバッファへコピーします: name。次のパラメーター、sizeは、次の引数が指すバッファのサイズを指定します: name。バッファには、スレッド名と末尾のNULを格納できる十分な大きさが必要です。足りない場合は、末尾のNULを含めて収まるよう名前を切り詰めます。

スレッド終了後の呼び出しは未定義動作です。

Windows Server 2016ではサポートせず、次のエラーを返します: UV_ENOSYS。

バージョン1.50.0で追加。

int uv_thread_setpriority(uv_thread_t tid, int priority)

成功時は0、失敗時は0未満の値を返します。tidで指定したスレッドのスケジューリング優先度を設定します。一部のプラットフォームでは、特定の優先度を設定するために高い権限が必要です。優先度は次の定数に設定できます: UV_THREAD_PRIORITY_HIGHEST、UV_THREAD_PRIORITY_ABOVE_NORMAL、UV_THREAD_PRIORITY_NORMAL、UV_THREAD_PRIORITY_BELOW_NORMAL、UV_THREAD_PRIORITY_LOWEST。

スレッド終了後の呼び出しは未定義動作です。

バージョン1.48.0で追加。

int uv_thread_getpriority(uv_thread_t tid, int *priority)

成功時は0、失敗時は0未満の値を返します。tidで指定したスレッドのスケジューリング優先度を取得します。出力パラメーターpriorityの値はプラットフォームに依存します。Linuxでは、スケジューリングポリシーがSCHED_OTHER(デフォルト)の場合、優先度は0です。

スレッド終了後の呼び出しは未定義動作です。

バージョン1.48.0で追加。

スレッドローカルストレージ

注記

スレッドローカルストレージの合計サイズには制限がある場合があります。つまり、多数のTLSキーを作成できない場合があります。

int uv_key_create(uv_key_t *key)
void uv_key_delete(uv_key_t *key)
void *uv_key_get(uv_key_t *key)
void uv_key_set(uv_key_t *key, void *value)

1回だけ行う初期化

関数を1回だけ実行します。同じガードを使って次の関数、uv_once()を同時に呼び出すと、1つを除くすべての呼び出し元がブロックされます(どれがブロックされないかは規定していません)。ガードはUV_ONCE_INITマクロで静的に初期化してください。

void uv_once(uv_once_t *guard, void (*callback)(void))

ミューテックスロック

関数は、成功時に0、失敗時に0未満のエラーコードを返します(もちろん、戻り値の型がvoidの場合を除きます)。

int uv_mutex_init(uv_mutex_t *handle)
int uv_mutex_init_recursive(uv_mutex_t *handle)
void uv_mutex_destroy(uv_mutex_t *handle)
void uv_mutex_lock(uv_mutex_t *handle)
int uv_mutex_trylock(uv_mutex_t *handle)
void uv_mutex_unlock(uv_mutex_t *handle)

読み書きロック

関数は、成功時に0、失敗時に0未満のエラーコードを返します(戻り値の型がvoidの場合を除きます)。

int uv_rwlock_init(uv_rwlock_t *rwlock)
void uv_rwlock_destroy(uv_rwlock_t *rwlock)
void uv_rwlock_rdlock(uv_rwlock_t *rwlock)
int uv_rwlock_tryrdlock(uv_rwlock_t *rwlock)
void uv_rwlock_rdunlock(uv_rwlock_t *rwlock)
void uv_rwlock_wrlock(uv_rwlock_t *rwlock)
int uv_rwlock_trywrlock(uv_rwlock_t *rwlock)
void uv_rwlock_wrunlock(uv_rwlock_t *rwlock)

セマフォ

関数は、成功時に0、失敗時に0未満のエラーコードを返します(戻り値の型がvoidの場合を除きます)。

int uv_sem_init(uv_sem_t *sem, unsigned int value)
void uv_sem_destroy(uv_sem_t *sem)
void uv_sem_post(uv_sem_t *sem)
void uv_sem_wait(uv_sem_t *sem)
int uv_sem_trywait(uv_sem_t *sem)

条件変数

関数は、成功時に0、失敗時に0未満のエラーコードを返します(戻り値の型がvoidの場合を除きます)。

注記

  1. 呼び出し元は、次の関数での疑似的なウェイクアップに対処できるようにしてください: uv_cond_wait()およびuv_cond_timedwait()。

  2. 次の関数、uv_cond_timedwait()のtimeoutパラメーターは、関数を呼び出した時刻を基準とする相対値です。

  3. z/OSでは、次の関数、uv_cond_timedwait()のtimeoutパラメーターを、待機が終了するシステム時刻の絶対値へ変換します。条件が通知される前に現在のシステム時刻が計算済みの絶対時刻を過ぎると、ETIMEDOUTエラーとなります。待機の開始後は、システムクロックの変更によって待機時間は変わりません。

int uv_cond_init(uv_cond_t *cond)
void uv_cond_destroy(uv_cond_t *cond)
void uv_cond_signal(uv_cond_t *cond)
void uv_cond_broadcast(uv_cond_t *cond)
void uv_cond_wait(uv_cond_t *cond, uv_mutex_t *mutex)
int uv_cond_timedwait(uv_cond_t *cond, uv_mutex_t *mutex, uint64_t timeout)

バリア

関数は、成功時に0、失敗時に0未満のエラーコードを返します(戻り値の型がvoidの場合を除きます)。

注記

uv_barrier_wait()は、後始末を容易にするため、任意に選ばれた「serializer」スレッドに0より大きい値を返します。次の例のように使います:

if (uv_barrier_wait(&barrier) > 0)
    uv_barrier_destroy(&barrier);
int uv_barrier_init(uv_barrier_t *barrier, unsigned int count)
void uv_barrier_destroy(uv_barrier_t *barrier)
int uv_barrier_wait(uv_barrier_t *barrier)