【C言語】threads.hでスレッドを扱う【標準ライブラリ】
目次
threads.hとは
threads.h
はC11標準で導入されたスレッド機能を提供するヘッダーファイルです。
従来、C言語でマルチスレッドを実装するにはPOSIXスレッド(pthread)やWindowsのスレッドAPIを使用する必要がありましたが、
threads.h
を使うことで、C11準拠のシンプルな方法でスレッドを扱うことができます。
提供される主な機能は以下のとおりです。
- スレッドの作成と終了
- スレッドの同期(ミューテックス、条件変数)
- スレッドローカルストレージ
スレッドの作成
スレッドを作成するには thrd_create()
を使用します。
スレッド関数は int
を返し、引数として void*
型のデータを受け取る必要があります。
#include <stdio.h>
#include <threads.h>
int thread_func(void *arg) {
printf("スレッドID: %d, 引数: %d\n", thrd_current(), *(int*)arg);
return 0;
}
int main() {
thrd_t thread;
int arg = 42;
if (thrd_create(&thread, thread_func, &arg) != thrd_success) {
printf("スレッドの作成に失敗しました。\n");
return 1;
}
thrd_join(thread, NULL);
return 0;
}
スレッドの同期
スレッドが終了するまで待機するには thrd_join()
を使用します。
これにより、スレッドの戻り値を取得することもできます。
#include <stdio.h>
#include <threads.h>
int thread_func(void *arg) {
printf("スレッド実行中...\n");
return 42;
}
int main() {
thrd_t thread;
int result;
thrd_create(&thread, thread_func, NULL);
thrd_join(thread, &result);
printf("スレッドの戻り値: %d\n", result);
return 0;
}
ミューテックスの使用
複数のスレッドが同じリソースを扱う場合、データ競合を防ぐために mtx_t
を使用します。
#include <stdio.h>
#include <threads.h>
mtx_t mutex;
int counter = 0;
int thread_func(void *arg) {
for (int i = 0; i < 5; i++) {
mtx_lock(&mutex);
counter++;
printf("スレッドID: %d, カウンター: %d\n", thrd_current(), counter);
mtx_unlock(&mutex);
}
return 0;
}
int main() {
thrd_t thread1, thread2;
mtx_init(&mutex, mtx_plain);
thrd_create(&thread1, thread_func, NULL);
thrd_create(&thread2, thread_func, NULL);
thrd_join(thread1, NULL);
thrd_join(thread2, NULL);
mtx_destroy(&mutex);
return 0;
}
条件変数の使用
条件変数 (cnd_t
) を使用すると、スレッドが特定の条件を満たすまで待機できます。
#include <stdio.h>
#include <threads.h>
mtx_t mutex;
cnd_t cond;
int ready = 0;
int worker(void *arg) {
mtx_lock(&mutex);
while (!ready) {
cnd_wait(&cond, &mutex);
}
printf("スレッドが条件を満たしました!\n");
mtx_unlock(&mutex);
return 0;
}
int main() {
thrd_t thread;
mtx_init(&mutex, mtx_plain);
cnd_init(&cond);
thrd_create(&thread, worker, NULL);
thrd_sleep(&(struct timespec){.tv_sec = 1}, NULL);
mtx_lock(&mutex);
ready = 1;
cnd_signal(&cond);
mtx_unlock(&mutex);
thrd_join(thread, NULL);
cnd_destroy(&cond);
mtx_destroy(&mutex);
return 0;
}
スレッドローカルストレージ
スレッドごとに異なるデータを保持するには、 thread_local
修飾子を使用します。
#include <stdio.h>
#include <threads.h>
thread_local int local_var = 0;
int thread_func(void *arg) {
local_var += (int)(intptr_t)arg;
printf("スレッドID: %d, local_var: %d\n", thrd_current(), local_var);
return 0;
}
int main() {
thrd_t thread1, thread2;
thrd_create(&thread1, thread_func, (void*)(intptr_t)10);
thrd_create(&thread2, thread_func, (void*)(intptr_t)20);
thrd_join(thread1, NULL);
thrd_join(thread2, NULL);
return 0;
}
まとめ
C11の threads.h
は、シンプルでポータブルなマルチスレッドプログラミングを実現するためのヘッダーです。
スレッドの作成、同期、ミューテックス、条件変数、スレッドローカルストレージといった基本機能を提供し、
POSIXスレッドに比べて記述が簡潔になります。