TLS-线程局部存储
概念
线程局部存储(Thread Local Storage,即TLS)用于将数据与一个正在执行的指定线程关联起来,以实现线程的私有数据存储.
进程
中的全局变量和函数中的静态变量是各个线程
都可以访问的共享变量,在一个线程进行修改,会影响到其他线程.虽然这样很方便数据的交换,但是不够安全,并且带来了很大的同步开销,也容易出bug.
TLS机制
就是用来实现在一个线程内部可访问,其他线程无法访问的变量,即static memory local to a thread,线程局部静态变量
,或Thread-Specific Data,TSD,线程特有数据
.
该机制在不同操作系统下的实现方式各不相同,对应的系统API也不相同,大多数操作系统都已实现.
linux实现
API如下:
1 |
|
其中:
- pthread_key_create : 为线程局部存储创建一个新的key,该key为全局所有线程可见的,线程退出时会调用destructor释放分配的缓存.
- pthread_key_delete : 删除一个键,删除后,该key占用的内存被释放,注销一个TSD(并不会检查是否有线程正在使用)
- pthread_setspecific : 设置对应key的具体的数据
- pthread_getspecific : 获取对应key的具体的数据
pthread_setspecific将一个变量的地址传入,与key关联;pthread_getspecific则获取到该地址,用于操作数据.
不同的线程中操作同一个key,不会冲突,不同线程使用同一个key得到的地址是各自之前set的值,互不影响.
如此,可以写一份线程代码,使用同一个key来多线程操作不同的数据.
使用pthread_setspecific为一个键指定新的数据时,线程必须释放原来的线程数据以回收空间.
由于删除一个键时,与该键关联的线程数据并不被释放,因此线程数据必须在释放键之前完成.
windows实现
windows将TLS进行分块,分块数为TLS_MINIMUM_AVAILABLE
,该值默认为64:
1 | // winnt.h |
API如下:
1 | DWORD TlsAlloc(); |
其中:
- TlsAlloc : 获得一个索引,如果调用成功,则得到一个索引值,否则返回
TLS_OUT_OFF_INDEXES(0xffffffff)
- TlsSetValue : 通过索引设置数据
- TlsGetValue : 通过索引获取数据
- TlsFree : 释放索引和内存块
TLS回调函数
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 WAHAHA's blog!
评论