注:本篇非我一己之力所完成,最后发布在了《TIPI》这本电子书上。
了解线程安全之前,我们先回顾几点基础知识点,是我们后面分析学习的基础。
变量的作用域
从作用域上来说,C语言可以定义4种不同的变量:全局变量,静态全局变量,局部变量,静态局部变量。
下面仅从函数作用域的角度分析一下不同的变量,假设所有变量声明不重名。
- 全局变量(
int gVar;
),在函数外声明。全局变量,所有函数共享,在任何地方出现这个变量名都是指这个变量。 - 静态全局变量(
static sgVar
),其实也是所有函数共享,但是这个会有编译器的限制,算是编译器提供的一种功能。 - 局部变量(函数/块内的
int var;
),不共享,函数的多次执行中涉及的这个变量都是相互独立的,他们只是重名的不同变量而已。 - 局部静态变量(函数中的
static int sVar;
),本函数间共享,函数的每一次执行中涉及的这个变量都是这个同一个变量。
上面几种作用域都是从函数的角度来定义作用域的,可以满足所有我们对单线程编程中变量的共享情况。 现在我们来分析一下多线程的情况。
在多线程中,多个线程共享除函数调用栈之外的其他资源。 因此上面几种作用域从定义来看就变成了。
- 全局变量,所有函数共享,因此所有的线程共享,不同线程中出现的不同变量都是这同一个变量。
- 静态全局变量,所有函数共享,也是所有线程共享。
- 局部变量,此函数的各次执行中涉及的这个变量没有联系,因此,也是各个线程间也是不共享的。
- 静态局部变量,本函数间共享,函数的每次执行涉及的这个变量都是同一个变量,因此,各个线程是共享的。
线程安全资源管理器的由来
TSRM的实现
首先定义了如下几个非常重要的全局变量(这里的全局变量是多线程共享的)。
**tsrm_tls_table
的全拼 thread safe resource manager thread local storage table,用来存放各个线程的tsrm_tls_entry
链表。tsrm_tls_table_size
用来表示**tsrm_tls_table
的大小。id_count
作为全局变量资源的 id 生成器,是全局唯一且递增的。*resource_types_table
用来存放全局变量对应的资源。resource_types_table_size
表示*resource_types_table
的大小。
其中涉及到两个关键的数据结构 tsrm_tls_entry
和 tsrm_resource_type
。
有了这个大致的了解,下面通过仔细分析 TSRM 环境的初始化和资源 ID 的分配来理解这一完整的过程。