Muduo库源码剖析(三)——获取线程tid方法
相关知识点
__thread
__thread
修饰 表示使用 线程局部存储机制(threadlocal 机制) ,即会为修饰的变量在当前线程存储一份copy,别的线程是看不到这个变量的修改
__thread是GCC内置的线程局部存储设施,其存储效率可以和全局变量相比;
__thread变量在每一个线程中都有一份独立实例,各线程值是互不干扰的。
extern
在 C++ 中,extern
是一个关键字,用于在当前文件以外的地方声明一个变量或函数。其作用有以下两个方面:
-
声明外部变量:使用
extern
关键字可以在当前文件中声明一个在其他文件中定义的全局变量。这样,在当前文件中就可以使用这个变量,而不需要重新定义一遍。例如:// file1.cpp extern int count;// file2.cpp int count = 0;// main.cpp #include <iostream> extern int count;int main() {std::cout << "count = " << count << std::endl;return 0; }
在这个例子中,
count
变量在file1.cpp
中被声明为外部变量,然后在file2.cpp
中被定义为 0。在main.cpp
中,count
又被声明为外部变量,并被用于输出。 -
声明外部函数:使用
extern
关键字可以在当前文件中声明一个在其他文件中定义的函数。这样,在当前文件中就可以调用这个函数,而不需要重新定义一遍。 -
extern "C"
是使C++能够调用C写作的库文件的一个手段,如果要对编译器提示使用C的方式来处理函数的话,那么就要使用extern "C"来说明
__builtin_expect(EXP, N)
允许程序员将最有可能执行的分支告诉编译器进行优化。
意思是:EXP成立的概率很接近N。
实际还是表达式EXP,即
// 告诉编译t_cachedTid == 0 不大可能成立
if(__builtin_expect(t_cachedTid == 0, 0))
{cacheTid();
}
// 理解时可等价于
if(t_cachedTid == 0)
{cacheTid();
}
重点代码
// CurrentThread.h
#pragma once// 该头文件封装获取当前线程的函数
#include <unistd.h>
#include <sys/syscall.h>namespace CurrentThread
{// __thread实现每个线程中都有一份独立的 t_cachedTid 实例,互不干扰extern __thread int t_cachedTid;void cacheTid();inline int tid(){ // 告诉编译t_cachedTid == 0 不大可能成立// 表达式还是相当于 t_cachedTid == 0if(__builtin_expect(t_cachedTid == 0, 0)){cacheTid();}return t_cachedTid;}
}// CurrentThread.cc
#include "CurrentThread.h"namespace CurrentThread
{__thread int t_cachedTid = 0;void cacheTid(){if(t_cachedTid == 0){// 通过Linux系统调用,获取当前线程的tidt_cachedTid = static_cast<pid_t>(::syscall(SYS_gettid));}}
}