pthread_once()について

pthread_once()の使い方がよくわからなかったので調べてみた。 このページ(*)が分り易かったからまとめておく。

1. 用途

-初期化に使う --通常初期化はプログラムの開始時に実施*1 --でも、できない場合もある ---例えば、ライブラリを作成する場合、初期化してもらえるかわからん ---仕方ないから呼ばれた時に呼ばれた側で初期化しよう ---エントリポイントのすべてで初期化されたかを判定して初期化処理を書くのは馬鹿らしい --一回だけ実行する仕組みを作ろうぜ

→ pthread_once()

2. 定義

int pthread_once( pthread_once_t * once_control, void (*init_routine)(void));
once_control:制御変数。PTHREAD_ONCE_INIT で初期化。
init_routine:1回だけ呼ばれる初期化用関数。

3. 使い方の例

(*)にあるプログラムを実行しようと思ったんだけど、once_main.cが見つからなかったので、書いてみた。

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

extern void *thread_func1(void *);
extern void *thread_func2(void *);
extern void *thread_func3(void *);
extern void *thread_func4(void *);

int main(void)
{
        int i = 0, j = 0;
        int ret;
        pthread_t th[4];

        fprintf(stderr, "main starts!\n");

        ret = pthread_create(&th[i], NULL, thread_func1, NULL);
        if (ret != 0) {
                perror("pthread_create");
                goto out;
        }

        ret = pthread_create(&th[++i], NULL, thread_func2, NULL);
        if (ret != 0) {
                perror("pthread_create");
                goto out;
        }

        ret = pthread_create(&th[++i], NULL, thread_func3, NULL);
        if (ret != 0) {
                perror("pthread_create");
                goto out;
        }

        ret = pthread_create(&th[++i], NULL, thread_func4, NULL);
        if (ret != 0) {
                perror("pthread_create");
                goto out;
        }

out:
        while (j < i)
                pthread_join(th[j++], NULL);

        fprintf(stderr, "main ends\n");
        return 0;
}

これとonce_thread.cをビルドして実行するとこんな感じ。

$ ./once 
main starts!
in thread_func2, before once_func.
in thread_func3, before once_func.
in thread_func1, before once_func.
in thread_func4, now start.
initializing function Start!!
in thread_func4, now end.
initializing function End...
in thread_func2, after once_func.
in thread_func3, after once_func.
in thread_func2, mutex_lock OK.
in thread_func1, after once_func.
in thread_func2, mutex_unlock OK.
in thread_func2, timesec:[5.000698]
in thread_func3, mutex_lock OK.
in thread_func3, mutex_unlock OK.
in thread_func3, timesec:[6.001000]
in thread_func1, mutex_lock OK.
in thread_func1, mutex_unlock OK.
in thread_func1, timesec:[7.001423]
main ends

pthread_once()で実行するonce_func()は一度のみ実行されているし、同時に実行している他のスレッドはblockしてるのがわかる。

今日はここまで。

*1:コンストラクタとか