posixマルチスレッドセンシング--スレッド高度プログラミング(pthread_once)

3057 ワード

スレッドキーなどのposix変数を一度だけ初期化する必要がある場合があります(後述します).何度も初期化プログラムを行うとエラーが発生します.
    従来のシーケンスプログラミングでは、一次初期化は、ブール変数を使用して管理されることが多い.制御変数は静的に0に初期化され、初期化に依存するコードはすべてこの変数をテストすることができる.変数値が0の場合、初期化を実行し、変数を1に設定できます.後でチェックするコードは初期化をスキップします.
    しかし、マルチスレッドプログラムの設計では、事が複雑になります.複数のスレッドが同時に初期化シーケンスコードを実行する場合、2つのスレッドが制御変数が0であることを発見し、いずれも初期化を実行する可能性がありますが、このプロセスは1回しか実行されません.
posix変数の静的初期化が必要である場合、使用可能な方法は、変数の初期話を反発量で制御することである.しかし、変数を動的に初期化する必要がある場合があります.pthread_onceはずっと便利です. 
関数の原形:
pthread_once_t once_control=PTHREAD_ONCE_INIT;
int pthread_once(pthread_once_t *once_control,void (*init_routine)(void));

パラメータ:
once_control         せいぎょへんすう
init_routine         初期化関数
戻り値:
   正常に0を返すと、失敗するとエラー番号が返されます.
   タイプはpthread_once_tの変数は制御変数である.制御変数はPTHREAD_を使用する必要がありますONCE_INITマクロは静的に初期化される.
   pthread_once関数はまず制御変数をチェックし、初期化が完了したかどうかを判断し、完了すれば簡単に戻る.そうでなければpthread_onceは初期化関数を呼び出し、初期化が完了したことを記録する.1つのスレッドが初期の場合、別のスレッドがpthread_を呼び出すonceでは、スレッドが呼び出され、その既成完了初期話が戻るまで待機します.
/*
 * once.c
 *
 * Demonstrate the use of pthread_once() one-time
 * initialization.
 */
#include <pthread.h>
#include "errors.h"

pthread_once_t once_block = PTHREAD_ONCE_INIT;
pthread_mutex_t mutex;

/*
 * This is the one-time initialization routine. It will be
 * called exactly once, no matter how many calls to pthread_once
 * with the same control structure are made during the course of
 * the program.
 */
void once_init_routine (void)
{
    int status;

    status = pthread_mutex_init (&mutex, NULL);
    if (status != 0)
        err_abort (status, "Init Mutex");
}

/*
 * Thread start routine that calls pthread_once.
 */
void *thread_routine (void *arg)
{
    int status;

    status = pthread_once (&once_block, once_init_routine);
    if (status != 0)
        err_abort (status, "Once init");
    status = pthread_mutex_lock (&mutex);
    if (status != 0)
        err_abort (status, "Lock mutex");
    printf ("thread_routine has locked the mutex.
"); status = pthread_mutex_unlock (&mutex); if (status != 0) err_abort (status, "Unlock mutex"); return NULL; } int main (int argc, char *argv[]) { pthread_t thread_id; char *input, buffer[64]; int status; status = pthread_create (&thread_id, NULL, thread_routine, NULL); if (status != 0) err_abort (status, "Create thread"); status = pthread_once (&once_block, once_init_routine); if (status != 0) err_abort (status, "Once init"); status = pthread_mutex_lock (&mutex); if (status != 0) err_abort (status, "Lock mutex"); printf ("Main has locked the mutex.
"); status = pthread_mutex_unlock (&mutex); if (status != 0) err_abort (status, "Unlock mutex"); status = pthread_join (thread_id, NULL); if (status != 0) err_abort (status, "Join thread"); return 0; }