CurrentThread主要就是为了获得当前线程的id和获取调用堆栈,Thread封装了创建线程及相关的api
CurrentThread.h中声明的一些函数在Thread.cpp中定义,两者关系紧密,所以可以放在一起看
CurrentThread.h 源码注释
#ifndef MUDUO_BASE_CURRENTTHREAD_H #define MUDUO_BASE_CURRENTTHREAD_H #include "Types.h" namespace muduo{ //线程局部变量 namespace CurrentThread{ /* extern关键字:用在变量声明中常有这样一个作用,在*.cpp文件中声明一个全局变量,这个全局的变量如果要被引用, 就放在*.h中并用extern来声明。 */ //__thread修饰的变量在每个线程中有独立的实体,各个线程中的变量互不干扰。 //__thread只能修饰POD类型变量(与C兼容的原始数据)。 extern __thread int t_cachedTid;//缓存中的线程id extern __thread char t_tidString[32];//线程id的字符串形式 extern __thread int t_tidStringLength;//线程id字符串的长度 extern __thread const char* t_threadName;//线程名陈 void cacheTid();//在thread.cpp 中定义 inline int tid(){//本线程第一次调用的时候才进行系统调用,以后都是直接从thread local缓存的线程id拿到结果 /* 这个指令是gcc引入的,作用是允许程序员将最有可能执行的分支告诉编译器。这个指令的写法为:__builtin_expect(EXP, N)。 意思是:EXP==N的概率很大. 这是一种性能优化,在这里就表示t_cachedTid为正的概率大,即直接返回t_cachedTid的概率大 */ if(__builtin_expect(t_cachedTid==0,0)){ cacheTid(); } return t_cachedTid; } inline const char* tidString(){// for logging return t_tidString; } inline int tidStringLength(){// for logging return t_tidStringLength; } inline const char* name(){ return t_threadName; } bool isMainThread();//在thread.cpp 中定义 void sleepUsec(int64_t usec); // for testing string stackTrace(bool demangle); } } #endif
CurrentThread.cpp 源码注释
#include"CurrentThread.h" #include <cxxabi.h> #include <execinfo.h> #include <stdlib.h> #include <type_traits> #include <errno.h> #include <stdio.h> #include <unistd.h> #include <sys/prctl.h> #include <sys/syscall.h> #include <sys/types.h> #include <linux/unistd.h> namespace muduo{ //线程局部变量 namespace CurrentThread{ //__thread修饰的变量在每个线程中有独立的实体,各个线程中的变量互不干扰。 //__thread只能修饰POD类型变量(与C兼容的原始数据)。 __thread int t_cachedTid = 0; __thread char t_tidString[32]; __thread int t_tidStringLength = 6; __thread const char* t_threadName = "unknown"; /* C++11中引入了static_assert这个关键字,用来做编译期间的断言,因此叫作静态断言 static_assert(常量表达式,"提示字符串") 如果第一个参数常量表达式的值为false,会产生一条编译错误。 错误位置就是该static_assert语句所在行,第二个参数就是错误提示字符串。 性能方面:由于static_assert是编译期间断言,不生成目标代码,因此static_assert不会造成任何运行期性能损失 */ /* template< class T, class U > struct is_same; 如果T与U具有同一const-volatile限定的相同类型,则is_same<T,U>::value为true,否则为false。 要求pid_t必须是int类型 */ static_assert(std::is_same<int, pid_t>::value, "pid_t should be int"); /*void cacheTid(){ if (t_cachedTid == 0) { t_cachedTid=static_cast<pid_t>(::syscall(SYS_gettid)); } }*/ /* 该函数是用来获取调用堆栈,debug用 首先,关于调用堆栈:假设我们有几个函数,fun1,fun2,fun3,fun4,且fun1调用fun2,fun2调用fun3,fun3调用fun4. 在fun4运行过程中,我能可以从线程当前堆栈中了解到调用它的几个函数分别是谁。 从函数的顺序来看,fun4,fun