【C言語】threads.hでスレッドを扱う【標準ライブラリ】

【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スレッドに比べて記述が簡潔になります。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です