深夜開発

プログラミング備忘録

pthreadを使ったスレッド生成

pthread

一般的にPOSIXスレッドの標準実装ライブラリの事を指し、スレッドの生成や基本的な操作を行うことが出来る。 POSIXをサポートしている多くの環境(主にUnix系)で利用できる反面、標準では基本的な機能のみが提供されるため、環境に依存した高度な処理を行う場合には拡張命令を使用する必要がある。

Sample code

#include <stdio.h>
#include <pthread.h>

#define STACK_SIZE (512 * 1024)
#define SCHED_POLICY SCHED_OTHER
#define SCHED_PRIORITY 10

#define CLAMP(x, min_value, max_value) (x < min_value ? min_value : (max_value < x ? max_value : x))

struct thread_arg
{
    int r;
    int a;
    int b;
    int c;
};

// 生成したスレッドで実行する関数
void* thread_entry(void *args)
{
    auto targs = reinterpret_cast<thread_arg*>(args);
    targs->r = targs->a * targs->b + targs->c;

    return nullptr;
}

int main()
{
    pthread_attr_t attr;
    pthread_attr_init(&attr);

    // 生成するスレッドのスタックサイズを設定
    if (pthread_attr_setstacksize(&attr, STACK_SIZE) != 0) {
        pthread_attr_destroy(&attr);
        return 1;
    }

    // 呼び出しスレッドのスケジューリング属性を継承しないよう設定
    if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) != 0) {
        pthread_attr_destroy(&attr);
        return 2;
    }

    // スケジューリングポリシーを設定
    if (pthread_attr_setschedpolicy(&attr, SCHED_POLICY) != 0) {
        pthread_attr_destroy(&attr);
        return 3;
    }

    sched_param param;

    const int min_priority = sched_get_priority_min(SCHED_POLICY);
    const int max_priority = sched_get_priority_max(SCHED_POLICY);
    param.sched_priority = CLAMP(SCHED_PRIORITY, min_priority, max_priority);

    // スケジューリング優先度を設定
    if (pthread_attr_setschedparam(&attr, &param) != 0) {
        pthread_attr_destroy(&attr);
        return 4;
    }
    
    thread_arg args;
    args.r = 0;
    args.a = 10;
    args.b = 20;
    args.c = 30;

    // スレッドのハンドル
    pthread_t thread;

    // スレッドを生成、発行
    if (pthread_create(&thread, &attr, thread_entry, &args) != 0) {
        pthread_attr_destroy(&attr);
        return 5;
    }

    // スレッド属性を破棄
    pthread_attr_destroy(&attr);

    // スレッドの終了を待つ
    // スレッドの内部メモリを解放する為、pthread_join または pthread_detach を必ず呼ばなければならない
    pthread_join(thread, nullptr);

    // 結果を出力
    printf("value = %d\n", args.r);

    return 0;
}
出力
value = 230