C 言語で pthread_join 関数を使用する

胡金庫 2023年10月12日
  1. pthread_join 関数を使用して、スレッドの終了を待機する
  2. pthread_join 関数の戻り値を使用してエラーをチェックする
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
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C Thread