在 C 語言中使用 pthread_join 函式

Jinku Hu 2023年10月12日
  1. 使用 pthread_join 函式等待執行緒終止
  2. 使用 pthread_join 函式返回值檢查錯誤
在 C 語言中使用 pthread_join 函式

本文將介紹幾種如何在 C 語言中使用 pthread_join 函式的方法。

使用 pthread_join 函式等待執行緒終止

程式使用 pthread_create 函式建立執行緒,通常,它等待它們通過 pthread_join 函式終止。pthread_join 僅接受兩個引數:用於指定等待執行緒的執行緒 ID 和指向可以儲存指定執行緒的退出狀態的 void*的指標。如果使用者不想檢索等待的執行緒的退出程式碼,則應將 NULL 值作為第二個引數傳遞。在下面的示例中,我們演示了建立 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 函式返回值檢查錯誤

與設定 errno 全域性變數的函式相比,pthread_join 函式返回的整數值還指示不同的錯誤程式碼。如果呼叫成功,則返回值為 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
作者: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

DelftStack.com 創辦人。Jinku 在機器人和汽車行業工作了8多年。他在自動測試、遠端測試及從耐久性測試中創建報告時磨練了自己的程式設計技能。他擁有電氣/ 電子工程背景,但他也擴展了自己的興趣到嵌入式電子、嵌入式程式設計以及前端和後端程式設計。

LinkedIn Facebook

相關文章 - C Thread