ちゃっくのメモ帳

ちゃっくがメモしときたいことをメモしとくよ

pthread_barrier_waitを使用した同期についてのメモ

C言語のpthreadライブラリには同期機構としてpthread_barrierが実装されている。
これはバリア同期のためのライブラリである。(バリア同期についてはいつか記事を書こうと思ってます)

pthreadのバリア同期を使用するときはpthread_barrier_waitを使うことで条件が満たされるまで実行がブロックされる。
これはシグナルが送られるまで実行をブロックする。そのためCPU時間を消費しない。
pthread_barrier_waitのmanを見るとsignalって文字は出てくるんだけど明示的にbusywaitじゃなくてsignalを使用してCPU時間を消費せずにブロックするって書かれていないので実験で確かめておきたくて実験をしたのでメモ。
CPU時間を消費しないことを確かめるために下のようなコードで実験をした。

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

#define THREAD_COUNT 2
pthread_barrier_t barrier;

void func1(){
    sleep(10);
    pthread_barrier_wait(&barrier);
}

void func2(){
    pthread_barrier_wait(&barrier);
}

int main(){
    int barrier_init = pthread_barrier_init(&barrier,NULL,THREAD_COUNT);
    pthread_t threads[THREAD_COUNT];

    pthread_create(&threads[0],NULL,(void*)func1,NULL);
    pthread_create(&threads[1],NULL,(void*)func2,NULL);

    pthread_join(threads[0],NULL);
    pthread_join(threads[1],NULL);
    return 0;
}

このコードはスレッド1は起動直後に10秒sleepする。このsleepはCPU時間を消費しない。
そしてスレッド2は起動直後にバリア同期によってwaitする。
バリア同期のカウントは2で設定しているのでスレッド1が10秒後にバリアに入らない限りスレッド2はブロックされる。
そして、スレッド1とスレッド2が終了するとプログラムは終了する。

このプログラムの実行時間をtimeコマンドで調べると次のような結果になる。

real 10.00
user 0.00
sys 0.00

ここで注目すべきはuserとsysである。
user modeでも, kernel modeでもCPU時間が消費されていない。
これでpthread_barrierによるブロックの間はCPU時間は消費されないことを確認できた。
(もし、CPU時間を消費するのならスレッド2は10秒分のCPU時間を消費しているはずなので)

pthreadライブラリにはspin_lockのライブラリもある。これはビジーウェイトしているように見えるのでCPU時間を消費するかもしれない(未検証)。


pthread_barrierがブロック中にCPU時間を消費しないことを確認したかったので行った実験なので面白いものではないのですが、この辺り明示的に書いてあるところって無いのかなぁ.....

詳解UNIXプログラミング 第3版

詳解UNIXプログラミング 第3版