getpid()
获得进程的PID一样。什么?此人要求Linux特定的,getpid()
在BSD或Apple中没有等效项。答案是gettid()
并返回整数类型。您需要使用syscall()
调用它,像这样:
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
....
pid_t x = syscall(__NR_gettid);
虽然这可能不适用于非Linux系统,但线程 ID 是可以直接进行比较且获取速度非常快的。它可以像普通整数一样打印(例如用于 LOGs)。
getpid()
只是举例而已,并没有说语义是硬规范。让人们意识到以符合 POSIX 的方式进行操作,这样除了 Linux 社区(如 FreeBSD、Illumos、OS X 等)外,其他社区也可以从中受益,这并不是在炫耀。就像我之前说的,我想 Linux 真的已经成为了下一个 Windows。 - Jasper Siepkesgcc --version
gcc (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0
,我不得不在所有的包含文件之前添加#define _GNU_SOURCE
,以便定义syscall()
。我从这里文档底部的示例中学到了这一点:https://man7.org/linux/man-pages/man2/syscall.2.html。 - Gabriel Staplespthread_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的可靠性。我已经参考了http://www.opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.h上的链接,但不确定是否正确。 - Vivek Maranpthread_t
在 Linux 中是一种指针。因此,如果您多次运行相同的程序,则可能会看到相同的 pthread_t
,而实际的线程是不同的。因此,打印 pthread_t
并没有太大帮助。 - U. Windl正如其他答案所述,pthreads没有定义一个跨平台的方法来检索整数线程 ID。
在Linux系统上,您可以这样获取线程ID:
#include <sys/types.h>
pid_t tid = gettid();
在许多基于BSD的平台上,这个答案https://dev59.com/q2Ei5IYBdhLWcg3wpdjJ#21206357提供了一种非可移植的方法。
然而,如果你认为需要线程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?。
pid_t tid = syscall(SYS_gettid);
Linux 提供了这样的系统调用,允许您获取线程的 id。
pthread_self()
函数。pthread_create()
后,父线程可以知道线程ID,但是在执行线程时,如果我们想要访问线程ID,则必须使用函数 pthread_self()
。这一行代码可以为您提供进程ID,每个线程ID和SPID。
printf("before calling pthread_create getpid: %d getpthread_self: %lu tid:%lu\n",getpid(), pthread_self(), syscall(SYS_gettid));
我认为不仅问题不清楚,大多数人也不了解其中的区别。看一下下面这句话:
在我看来,只有一种可移植的方式可以将定义一个变量以升序保存数字的结构体传递给每个线程。通过这样做,可以跟踪线程的ID。然而,应该使用POSIX线程ID并不同于Linux特有的
gettid()
系统调用返回的线程ID。 POSIX线程ID由线程实现分配和维护。由内核分配的是gettid()
返回的线程ID号码(类似于进程ID)。尽管在Linux NPTL线程实现中,每个POSIX线程都有一个唯一的内核线程ID,但应用程序通常不需要知道内核ID(如果依赖于它们,将无法移植)。摘自:The Linux Programming Interface: A Linux and UNIX System Programming Handbook, Michael Kerrisk
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.在这里的答案:https://dev59.com/aWEi5IYBdhLWcg3wb76O#21280941 - SRGpthread_getthreadid_np
在我的 Mac os x 上不存在。 pthread_t
是一个不透明的类型。 不要过于纠结,只需将其分配给void*
并调用即可。 如果需要使用printf
,请使用%p
。
还有一种获取线程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中定义为无符号长整型)。同时,最后一个参数 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
}
对于不同的操作系统,有不同的答案。我在这里找到了一个帮助程序这里。
你可以尝试这个:
#include <unistd.h>
#include <sys/syscall.h>
int get_thread_id() {
#if defined(__linux__)
return syscall(SYS_gettid);
#elif defined(__FreeBSD__)
long tid;
thr_self(&tid);
return (int)tid;
#elif defined(__NetBSD__)
return _lwp_self();
#elif defined(__OpenBSD__)
return getthrid();
#else
return getpid();
#endif
}