如何在linux c程序中获取pthread的线程ID?

时间:2014-01-13 12:12:29

标签: c linux pthreads

在linux c程序中,如何打印pthread库创建的线程的线程ID? 例如:我们可以通过getpid()

获取流程的pid

11 个答案:

答案 0 :(得分:68)

pthread_self()函数将给出当前线程的线程id。

pthread_t pthread_self(void);

pthread_self()函数返回调用线程的Pthread句柄。 pthread_self()函数不返回调用线程的整数线程。您必须使用pthread_getthreadid_np()返回线程的整数标识符。

注:

pthread_id_np_t   tid;
tid = pthread_getthreadid_np();

明显快于这些调用,但提供相同的行为。

pthread_id_np_t   tid;
pthread_t         self;
self = pthread_self();
pthread_getunique_np(&self, &tid);

答案 1 :(得分:52)

什么?该人要求Linux特定,相当于getpid()。不是BSD或Apple。答案是gettid()并返回一个整数类型。您必须使用syscall()调用它,如下所示:

#include <sys/types.h>
#include <sys/syscall.h>

 ....

 pid_t x = syscall(__NR_gettid);

虽然这可能无法移植到非Linux系统,但是threadid可以直接比较并且非常快速地获取。它可以像普通整数一样打印(例如用于LOG)。

答案 2 :(得分:8)

您可以使用pthread_self()

在成功执行pthread_create()之后父进程知道线程id,但是如果我们想要访问线程id,则在执行线程时我们必须使用函数pthread_self()

答案 3 :(得分:8)

正如其他答案所述,pthreads没有定义与平台无关的方法来检索整体线程ID。

在Linux系统上,您可以获得线程ID:

#include <sys/types.h>
pid_t tid = gettid();

在许多基于BSD的平台上,这个答案https://stackoverflow.com/a/21206357/316487提供了一种不可移植的方式。

但是,如果您认为需要线程ID的原因是要知道您是否在与您控制的另一个线程相同或不同的线程上运行,那么您可能会在此方法中找到一些实用程序

static pthread_t threadA;

// On thread A...
threadA = pthread_self();

// On thread B...
pthread_t threadB = pthread_self();
if (pthread_equal(threadA, threadB)) printf("Thread B is same as thread A.\n");
else printf("Thread B is NOT same as thread A.\n");

如果您只是需要知道自己是否在主线程中,还有其他方法,请在此问题的答案中记录how can I tell if pthread_self is the main (first) thread in the process?

答案 4 :(得分:8)

pid_t tid = syscall(SYS_gettid);

Linux提供此类系统调用以允许您获取线程的ID。

答案 5 :(得分:3)

这一行给你pid,每个threadid和spid。

 printf("before calling pthread_create getpid: %d getpthread_self: %lu tid:%lu\n",getpid(), pthread_self(), syscall(SYS_gettid));

答案 6 :(得分:3)

pthread_getthreadid_np不在我的Mac OS x上。 pthread_t是一种不透明的类型。不要打扰你的头。只需将其分配给void*并称之为好。如果您需要printf使用%p

答案 7 :(得分:2)

还有另一种获取线程ID的方法。使用

创建线程时

int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *), void *arg);

函数调用;第一个参数pthread_t * thread实际上是一个线程id(在bits / pthreadtypes.h中定义的unsigned long int)。此外,最后一个参数void *arg是传递给void * (*start_routine)函数的参数。

您可以创建一个结构来传递多个参数并发送指向结构的指针。

typedef struct thread_info {
    pthread_t thread;
    //...
} thread_info;
//...
tinfo = malloc(sizeof(thread_info) * NUMBER_OF_THREADS);
//...
pthread_create (&tinfo[i].thread, NULL, handler, (void*)&tinfo[i]);
//...
void *handler(void *targs) {
    thread_info *tinfo = targs;
    // here you get the thread id with tinfo->thread
}

答案 8 :(得分:1)

我认为不仅这个问题不清楚,而且大多数人也不了解这种差异。检查以下说法,

  

POSIX线程ID与线程返回的线程ID不同。   Linux特定的gettid()系统调用。分配POSIX线程ID   并由线程实现维护。返回的线程ID   由gettid()表示的是一个数字(类似于进程ID),由   内核。 尽管每个POSIX线程都有唯一的内核线程ID   在Linux NPTL线程实现中,通常是一个应用程序   不需要知道内核ID(如果可以的话,也不会移植)   取决于了解他们。)

     

摘录自:The Linux Programming Interface: A Linux and UNIX System Programming Handbook, Michael Kerrisk

恕我直言,只有一种可移植的方式可以通过一种结构,在该结构中以递增方式(例如, 1,2,3...至每个线程。通过这样做,可以跟踪线程的ID。尽管如此,仍应使用int pthread_equal(tid1, tid2)函数。

if (pthread_equal(tid1, tid2)) printf("Thread 2 is same as thread 1.\n");
else printf("Thread 2 is NOT same as thread 1.\n");

答案 9 :(得分:0)

与平台无关的方式(从c ++ 11开始)是:

#include <thread>

std::this_thread::get_id();

答案 10 :(得分:-1)

您也可以以这种方式编写,并且执行相同的操作。例如:

for(int i=0;i < total; i++)
{
    pthread_join(pth[i],NULL);
    cout << "SUM of thread id " << pth[i] << " is " << args[i].sum << endl;
}

该程序设置一个pthread_t数组并计算每个数组的和。因此,它正在打印具有线程ID的每个线程的总和。