在 C 語言中獲取執行緒 ID

Jinku Hu 2023年1月30日 2021年2月28日
  1. 使用 pthread_self 函式在 C 語言中獲取執行緒 ID
  2. 在 C 語言中使用 gettid 函式獲取執行緒 ID
  3. 使用 thrd_current 函式獲取 C 語言中的執行緒 ID
在 C 語言中獲取執行緒 ID

本文將演示關於如何在 C 語言中獲取執行緒 ID 的多種方法。

使用 pthread_self 函式在 C 語言中獲取執行緒 ID

執行緒是當代 CPU 效能的基石,因為現在的 CPU 往往會增加更多的虛擬或物理核心,以支援更好的多執行緒工作流。一般來說,執行緒被表示為一個程序(即正在執行的程式)中的單一控制流。因此,執行緒是用來實現多個邏輯流,這些邏輯流會併發執行,形成一個利用多個 CPU 核的程式。請注意,POSIX 執行緒一直是 C 程式中訪問執行緒設施的最古老的標準介面。pthread_selfpthreads API 提供的函式之一,可以檢索呼叫執行緒的 ID。它接受零引數,並返回表示執行緒 ID 的整數作為 pthread_t 型別變數。

在下面的示例程式碼中,我們實現了基本的多執行緒方案,主程式(執行緒)建立了額外的四個執行緒,它們執行 printHello 函式,並使用 pthread_exit 函式呼叫終止。注意,在這個程式中,有五個執行緒在執行,並且在執行完給定的程式碼路徑後全部退出。在 printHello 函式中,所有的執行緒都使用 pthread_self 函式列印自己的執行緒 ID。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#ifndef NUM_THREADS
#define NUM_THREADS 4
#endif

void *printHello(void *threadid) {
    long tid;
    tid = (long)threadid;
    printf("Hello There! thread %ld, pthread ID - %lu\n", tid, pthread_self());
    pthread_exit(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);
        }
    }
    pthread_exit(NULL);
}

輸出:

Hello There! thread 1, pthread ID - 140388002486016
Hello There! thread 0, pthread ID - 140388010878720
Hello There! thread 2, pthread ID - 140387994093312
Hello There! thread 3, pthread ID - 140387985700608

在 C 語言中使用 gettid 函式獲取執行緒 ID

gettid 是 Linux 特有的系統呼叫,是使用 C 程式中的函式封裝器提供的,它返回撥用者的執行緒 ID。該函式不接受類似於 pthread_self 的引數,返回 pid_t 型別的整數值。需要注意的是,gettid 呼叫返回的值與 pthread_self 函式檢索到的 ID 不一樣,後者稱為 POSIX 執行緒 ID。如果程式是單執行緒的,gettid 返回的值與 getpid 相同-等於程序 ID。

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#ifndef NUM_THREADS
#define NUM_THREADS 4
#endif

void *printHello(void *threadid) {
    long tid;
    tid = (long)threadid;
    printf("Hello There! thread %ld, kthread ID - %d\n", tid, gettid());
    pthread_exit(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);
        }
    }
    pthread_exit(NULL);
}

輸出:

Hello There! thread 0, kthread ID - 10389
Hello There! thread 1, kthread ID - 10390
Hello There! thread 2, kthread ID - 10391
Hello There! thread 3, kthread ID - 10392

使用 thrd_current 函式獲取 C 語言中的執行緒 ID

thrd_current 是 2011 年加入標準語言規範的 ISO C 執行緒 API 的一部分。請注意,這個 API 為 POSIX 相容的作業系統和任何提供符合標準的 C 編譯器的平臺提供了一個標準介面。因此,這種方法是推薦的與 C 語言中執行緒互動的方式。在下面的例子中,我們使用 pthread 函式來建立和退出執行緒,儘管如此,在專案工作時,應該選擇一個單一的介面(Pthreads 或 ISO C)。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <threads.h>

#ifndef NUM_THREADS
#define NUM_THREADS 4
#endif

void *printHello(void *threadid) {
    long tid;
    tid = (long)threadid;
    printf("Hello There! thread %ld, pthread ID - %lu\n", tid, thrd_current());
    pthread_exit(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);
        }
    }
    pthread_exit(NULL);
}

輸出:

Hello There! thread 0, pthread ID - 139727514998528
Hello There! thread 1, pthread ID - 139727506605824
Hello There! thread 2, pthread ID - 139727498213120
Hello There! thread 3, pthread ID - 139727489820416
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn

相關文章 - C Thread