在Linux C程序中,如何打印pthread库创建的线程的线程ID?
例如:我们可以通过getpid()
在Linux C程序中,如何打印pthread库创建的线程的线程ID?
例如:我们可以通过getpid()
Answers:
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);
pthread_threadid_np
。我需要用于一个项目,因此需要检查iOS和OSX平台中该API的可靠性。请参考opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.h上的链接,但不确定它们是否正确。
_np
表示不可携带。Linux有自己的_np
东西,但不包括Apple的东西pthread_getthreadid_np
。
什么?该人员要求提供特定于Linux的内容,等效于getpid()。不是BSD或Apple。答案是gettid()并返回整数类型。您将必须使用syscall()来调用它,如下所示:
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
....
pid_t x = syscall(__NR_gettid);
尽管这可能无法移植到非Linux系统,但是threadid是直接可比的,并且获取速度非常快。可以像普通整数一样打印(例如用于LOG)。
getpid()
仅作为示例。它并没有说语义是一个严格的规范。让人们意识到以POSIX兼容的方式来做事,这样Linux之外的其他社区(例如FreeBSD,Illumos,OS X等)也可以从中受益,这并不是“炫耀”。就像我说的,我猜Linux确实已经成为下一个Windows。
如其他答案所述,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");
如果您只需要知道自己是否在主线程上,还有其他方法,请参见此问题的答案,我如何确定pthread_self是否是进程中的主(第一个)线程?。
pthread_getthreadid_np
不在我的Mac OS X上。 pthread_t
是不透明的类型。不要把头撞过去。只需将其分配给void*
并称其为好即可。如果需要printf
使用%p
。
我认为不仅这个问题不清楚,而且大多数人也不了解这种差异。检查以下说法:
POSIX线程ID与Linux特定
gettid()
系统调用返回的线程ID不同。POSIX线程ID由线程实现分配和维护。返回的线程IDgettid()
是内核分配的数字(类似于进程ID)。尽管在Linux NPTL线程实现中,每个POSIX线程都有一个唯一的内核线程ID,但是应用程序通常不需要知道内核ID(并且,如果依赖于它们,就不会具有可移植性)。
恕我直言,只有一种可移植的方式可以传递一种结构,在该结构中以递增方式(例如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");
gettid()
实际上是一个很好的建议,谢谢!但是,我需要在这里关注Sergey L.的回答:stackoverflow.com/a/21280941/2430526
还有另一种获取线程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中定义的无符号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
}
您也可以以这种方式编写,并且执行相同的操作。例如:
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的每个线程的总和。