muduo_base 04 (Thread)

本文源码基于muduo v2.0.2分析

pid,pthread_id,tid

getpid()获取的是进程id,类型pid_t,每个进程在os中有唯一的ID

pthread_self()获取的是线程ID,线程ID在某进程中是唯一的,在不同的进程中创建的线程可能出现ID值相同的情况。类型为pthread_t。

Linux中的POSIX线程又被称为LWP(轻量级进程),不管创建线程还是进程都是调用的fork,只是线程共享了部分资源而已。所以POSIX线程还具有一个唯一的真实pid,通常被称为tid。Linux下pid_t gettid(void);可以得到tid,man page的note指出Glibc does not provide a wrapper for this system call; call it using syscall(2).,glibc没有封装改函数,如需使用通过syscall(SYS_gettid)

__thread

gcc内置的线程局部存储设施

__thread只能修饰POD(plain old data)类型。POD类型指与C兼容的原始数据,例如,结构和整数等C语言中的类型是POD类型,但带有用户定义的构造函数或虚函数的类则不是。非POD类型可以使用线程特定数据TSD

CurrentThread.cc

__thread int t_cachedTid = 0;   //缓存tid
__thread char t_tidString[32];  //tid字符串表示
__thread int t_tidStringLength = 6;
__thread const char* t_threadName = "unknown";

被__thread修饰的变量为每个线程各自的全局变量。一个线程的修改不会对其他线程产生影响。

C++11标准有thread_local,相比__thread有延迟初始化开销。更多不同请见文末参考资料。

pthread_atfork()

改函数注册fork函数调用前后的句柄

#include <pthread.h>

int pthread_atfork(void (*prepare)(void), void (*parent)(void),
                    void (*child)(void));

三个参数分别为调用fork前,调用fork后父进程,调用fork后子进程的句柄。置为NULL即为不注册,成功时返回0,失败返回错误码。

Reference

thread_local与__thread的区别