pthread_once() - 関数の 1 回呼び出し

標準

標準/拡張機能 C/C++ 依存項目

POSIX.4a
Single UNIX Specification、バージョン 3

両方

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)());
SUSV3:
#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
⁄* 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

関連情報