posixマルチスレッドセンシング--スレッド高度プログラミング(pthread_once)
3057 ワード
スレッドキーなどのposix変数を一度だけ初期化する必要がある場合があります(後述します).何度も初期化プログラムを行うとエラーが発生します.
従来のシーケンスプログラミングでは、一次初期化は、ブール変数を使用して管理されることが多い.制御変数は静的に0に初期化され、初期化に依存するコードはすべてこの変数をテストすることができる.変数値が0の場合、初期化を実行し、変数を1に設定できます.後でチェックするコードは初期化をスキップします.
しかし、マルチスレッドプログラムの設計では、事が複雑になります.複数のスレッドが同時に初期化シーケンスコードを実行する場合、2つのスレッドが制御変数が0であることを発見し、いずれも初期化を実行する可能性がありますが、このプロセスは1回しか実行されません.
posix変数の静的初期化が必要である場合、使用可能な方法は、変数の初期話を反発量で制御することである.しかし、変数を動的に初期化する必要がある場合があります.pthread_onceはずっと便利です.
関数の原形:
パラメータ:
once_control せいぎょへんすう
init_routine 初期化関数
戻り値:
正常に0を返すと、失敗するとエラー番号が返されます.
タイプはpthread_once_tの変数は制御変数である.制御変数はPTHREAD_を使用する必要がありますONCE_INITマクロは静的に初期化される.
pthread_once関数はまず制御変数をチェックし、初期化が完了したかどうかを判断し、完了すれば簡単に戻る.そうでなければpthread_onceは初期化関数を呼び出し、初期化が完了したことを記録する.1つのスレッドが初期の場合、別のスレッドがpthread_を呼び出すonceでは、スレッドが呼び出され、その既成完了初期話が戻るまで待機します.
従来のシーケンスプログラミングでは、一次初期化は、ブール変数を使用して管理されることが多い.制御変数は静的に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;
}