打日志的时候,我们希望把线程 id 打印出来,线程 id 有两个方法可以获取,gettid 和 pthread_self,前者是一个 Linux 的系统调用,后者是一个可移植的库函数,可移植性倒还好,因为也不怎么考虑跨平台,另外一个区别,就是他们的返回值不一样,这个可以看到这里,http://stackoverflow.com/quest…,有一个讨论,摘录如下:
They are not the same. Here are some bits I collected from TLPI (I couldn’t find a large-enough block that completely describes this). If you’re in a hurry you probably want just the last part.
gettid
Linux 2.4 introduced a new system call, gettid(), to allow a thread to obtain its own thread ID.
Each thread within a thread group is distinguished by a unique thread identifier. A thread ID is represented using the same data type that is used for a process ID, pid_t. Thread IDs are unique system-wide, and the kernel guarantees that no thread ID will be the same as any process ID on the system, except when a thread is the thread group leader for a process.
pthread_self
Each thread within a process is uniquely identified by a thread ID. A thread can obtain its own ID using pthread_self().
The pthread_equal() function is needed to compare thread ids because the pthread_t data type must be treated as opaque data.
In the Linux threading implementations, thread IDs are unique across processes. However, this is not necessarily the case on other implementations, and SUSv3 explicitly notes that an application can’t portably use a thread ID to identify a thread in another process.
gettid vs pthread_self
POSIX thread IDs are not the same as the thread IDs returned by the Linux-specific gettid() system call. POSIX thread IDs are assigned and maintained by the threading implementation. The thread ID returned by gettid() is a number (similar to a process ID) that is assigned by the kernel.
I would go with pthread_setaffinity_np but be aware that the manual says:
These functions are implemented on top of the sched_setaffinity(2)
简单的说,就是一个是给出系统范围内的唯一 id,另外一个是给出进程范围内的唯一值,这个也不太重要吧,另外这里,给出了一些源码的跟踪,http://zhwen.org/xlog/?p=622,接下来就是考虑性能问题了,首先来看 pthread_self
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <pthread.h>
#include <iostream>
#define gettid() syscall(__NR_gettid)
int main() {
//pid_t tid;
pthread_t tid;
int iTestCase = 10000000;
while (iTestCase--) {
//tid = gettid();
tid = pthread_self();
tid++;
}
std::cout<<tid<<std::endl;
return 0;
}
那个自增,是为了防止编译器优化,输出如下
$ time ./a.out 47071132892337 real 0m0.036s user 0m0.036s sys 0m0.000s
话说这个 id 还真是长啊。。然后来看看 gettid 的情况
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <pthread.h>
#include <iostream>
#define gettid() syscall(__NR_gettid)
int main() {
pid_t tid;
//pthread_t tid;
int iTestCase = 10000000;
while (iTestCase--) {
tid = gettid();
//tid = pthread_self();
tid++;
}
std::cout<<tid<<std::endl;
return 0;
}
来看耗时
$ time ./a.out 3904 real 0m0.543s user 0m0.236s sys 0m0.308s
居然慢了几乎 18 倍,这个差距就太大了