C 言語で pthread_join 関数を使用する
この記事では、C 言語で pthread_join
関数を使用する方法のいくつかの方法について説明します。
pthread_join
関数を使用して、スレッドの終了を待機する
プログラムは、pthread_create
関数を使用してスレッドを作成し、通常、pthread_join
関数を使用してスレッドが終了するのを待ちます。pthread_join
は 2つの引数のみを取ります。待機中のスレッドを指定するスレッド ID と、指定されたスレッドの終了ステータスを格納できる void*
へのポインターです。ユーザーが待機中のスレッドの終了コードを取得したくない場合は、NULL
値を 2 番目の引数として渡す必要があります。次の例では、8つのスレッドを作成し、それぞれで printHello
関数を実行するプログラムを示します。次に、呼び出し元のスレッドは、ループ内の pthread_join
呼び出しですべてのスレッドを待機します。スレッドの終了ステータスコードも retval
変数に格納し、int
にキャストしてその値を出力することに注意してください。ただし、スレッドがキャンセルされた場合、PTHREAD_CANCELED
値は retval
アドレスに配置されます。
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#ifndef NUM_THREADS
#define NUM_THREADS 8
#endif
void *printHello(void *threadid) {
long tid;
tid = (long)threadid;
printf("Hello from thread %ld, pthread ID - %lu\n", tid, pthread_self());
return NULL;
}
int main(int argc, char const *argv[]) {
pthread_t threads[NUM_THREADS];
int rc;
long t;
for (t = 0; t < NUM_THREADS; t++) {
rc = pthread_create(&threads[t], NULL, printHello, (void *)t);
if (rc) {
printf("ERORR; return code from pthread_create() is %d\n", rc);
exit(EXIT_FAILURE);
}
}
int ret;
for (t = 0; t < NUM_THREADS; t++) {
void *retval;
ret = pthread_join(threads[t], &retval);
if (retval == PTHREAD_CANCELED)
printf("The thread was canceled - ");
else
printf("Returned value %d - ", (int)retval);
}
pthread_exit(NULL);
}
出力:
Hello from thread 0, pthread ID - 140716669929216
Hello from thread 1, pthread ID - 140716661536512
Hello from thread 2, pthread ID - 140716653143808
Hello from thread 3, pthread ID - 140716644751104
Hello from thread 5, pthread ID - 140716627965696
Hello from thread 4, pthread ID - 140716636358400
Hello from thread 6, pthread ID - 140716550387456
Hello from thread 7, pthread ID - 140716541994752
pthread_join
関数の戻り値を使用してエラーをチェックする
pthread_join
関数は、errno
グローバル変数を設定する関数とは対照的に、さまざまなエラーコードも示す整数値を返します。呼び出しが成功した場合の戻り値は 0
であり、これにより、指定されたスレッドが終了したことが保証されます。返された整数が EDEADLK
と等しい場合、デッドロックが検出されたことを報告します。EINVAL
値が返された場合、指定されたスレッドは結合できません。値が ESRCH
と等しい場合、指定されたスレッド ID が見つからないことを示します。この場合、switch
ステートメントを実装して各ケースをチェックし、対応するメッセージを stdout
に出力します。
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#ifndef NUM_THREADS
#define NUM_THREADS 8
#endif
void *printHello(void *threadid) {
long tid;
tid = (long)threadid;
printf("Hello from thread %ld, pthread ID - %lu\n", tid, pthread_self());
return NULL;
}
int main(int argc, char const *argv[]) {
pthread_t threads[NUM_THREADS];
int rc;
long t;
for (t = 0; t < NUM_THREADS; t++) {
rc = pthread_create(&threads[t], NULL, printHello, (void *)t);
if (rc) {
printf("ERORR; return code from pthread_create() is %d\n", rc);
exit(EXIT_FAILURE);
}
}
int ret;
for (t = 0; t < NUM_THREADS; t++) {
void *retval;
ret = pthread_join(threads[t], &retval);
if (retval == PTHREAD_CANCELED)
printf("The thread was canceled - ");
else
printf("Returned value %d - ", (int)retval);
switch (ret) {
case 0:
printf("The thread joined successfully\n");
break;
case EDEADLK:
printf("Deadlock detected\n");
break;
case EINVAL:
printf("The thread is not joinable\n");
break;
case ESRCH:
printf("No thread with given ID is found\n");
break;
default:
printf("Error occurred when joining the thread\n");
}
}
pthread_exit(NULL);
}
出力:
Hello from thread 0, pthread ID - 140082577512192
Hello from thread 1, pthread ID - 140082569119488
Hello from thread 3, pthread ID - 140082552334080
Hello from thread 5, pthread ID - 140082535548672
Hello from thread 6, pthread ID - 140082527155968
Returned value 0 - The thread joined successfully
Hello from thread 4, pthread ID - 140082543941376
Hello from thread 2, pthread ID - 140082560726784
Returned value 0 - The thread joined successfully
Returned value 0 - The thread joined successfully
Returned value 0 - The thread joined successfully
Hello from thread 7, pthread ID - 140082518763264
Returned value 0 - The thread joined successfully
Returned value 0 - The thread joined successfully
Returned value 0 - The thread joined successfully
Returned value 0 - The thread joined successfully