在 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