標準/拡張機能 | C/C++ | 依存項目 |
---|---|---|
POSIX.4a |
両方 | POSIX(ON) |
#define _OPEN_THREADS
#include <pthread.h>
pthread_once_t once_control = PTHREAD_ONCE_INIT;
int pthread_once(pthread_once_t *once_control, void(*init_routine)());
#define _UNIX03_THREADS
#include <pthread.h>
pthread_once_t once_control = PTHREAD_ONCE_INIT;
int pthread_once(pthread_once_t *once_control, void(*init_routine)());
指定のプロセスで 1 回だけ実行される関数を設定します。各スレッドからこの関数を呼び出すことができますが、関数を実行できるのは最初の呼び出しだけです。これは、複数のスレッドによって同時に呼び出された場合も同じです。例えば、mutex またはスレッド固有のデータ・キーは 1 回だけ作成する必要が あります。pthread_once() の呼び出しの場合、mutex または スレッド固有のデータを作成するコードが 複数のスレッドで呼び出されることはありません。このルーチンを使用しない場合には、1 つのスレッドだけが初期設定を行うように、実行をシリアライズする必要があります。コードの同じ点に達した他のスレッドは、最初のスレッドが終了するまで待機します。
pthread_once() は、pthread_once_t 型の once control 変数と共に使用されます。 この変数は、PTHREAD_ONCE_INIT 定数に対して初期設定するデータ型です。その後、pthread_once() 関数呼び出しのパラメーターとして渡されます。
init_routine は標準関数です。 これは pthread_once() の外側で直接呼び出すことができます。さらに、init_routine が呼び出されているかどうかを判別するのは、once_control 変数です。同じルーチンと、異なる once_control 変数を 使用して pthread_once() を呼び出すと、ルーチンは once_control 変数 ごとに 1 回ずつ、つまり 2 回呼び出されることになります。
正常に実行された場合、pthread_once() は 0 を戻します。
正常に実行されなかった場合、pthread_once() は -1 を戻します。
設定される errno 値はありません。 perror() または strerror() を使用して、エラーの原因を判別してください。
Single UNIX Specification、バージョン 3 の特殊な動作: 正常に実行されなかった場合、pthread_once() はエラーを示すエラー番号を戻します。
⁄* CELEBP46 *⁄
#ifndef _OPEN_THREADS
#define _OPEN_THREADS
#endif
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#define threads 3
int once_counter=0;
pthread_once_t once_control = PTHREAD_ONCE_INIT;
void once_fn(void)
{
puts("in once_fn");
once_counter++;
}
void *threadfunc(void *parm)
{
int status;
int threadnum;
int *tnum;
tnum = parm;
threadnum = *tnum;
printf("Thread %d executing¥n", threadnum);
status = pthread_once(&once_control, once_fn);
if ( status < 0)
printf("pthread_once failed, thread %d, errno=%d¥n", threadnum,
errno);
pthread_exit((void *)0);
}
main() {
int status;
int i;
int threadparm[threads];
pthread_t threadid[threads];
int thread_stat[threads];
for (i=0; i<threads; i++) {
threadparm[i] = i+1;
status = pthread_create( &threadid[i],
NULL,
threadfunc,
(void *)&threadparm[i]);
if ( status < 0) {
printf("pthread_create failed, errno=%d", errno);
exit(2);
}
}
for ( i=0; i<threads; i++) {
status = pthread_join( threadid[i], (void *)&thread_stat[i]);
if ( status < 0)
printf("pthread_join failed, thread %d, errno=%d¥n", i+1, errno);
if (thread_stat[i] != 0)
printf("bad thread status, thread %d, status=%d¥n", i+1,
thread_stat[i]);
}
if (once_counter != 1)
printf("once_fn did not get control once, counter=%d",once_counter);
exit(0);
}
Thread 1 executing
in once_fn
Thread 2 executing
Thread 3 executing