之前的笔记搬运
线程局部存储(TLS)
0x1 什么是线程局部存储
在一个线程修改的内存内容,对所有线程都生效。这是一个优点也是一个缺点。多个线程访问共享数据,需要昂贵的同步开销,也容易造成同步相关的BUG。
如果需要在一个线程内部的各个函数调用都能访问、但其它线程不能访问的变量,就需要新的机制来实现。这就是线程局部存储(TLS)
0x2 为什么需要线程局部存储
在C库函数中, 大量引用了全局变量, 所以导致在多线程中使用,就会出现多线程同时使用一个全局变量, 导致数据出错的情况,一般这时候只要使用_beginThread这个函数来启动线程就可以避免这个问题,而这个函数里就是使用了线程局部存储技术;
0x3 怎么使用线程局部存储(TLS)
第一步,在主进程内调用TlsAlloc()函数,从将要启动的每个线程的TLS索引数组中预定一个条目(slot),并返回该条目的序号;
第二步,在每个进程执行的一开头,从堆中动态分配一块内存区域(使用LocalAlloc()函数调用)然后使用TlsSetValue()函数调用,把这块内存区域的地址存入TLS索引数组相应的条目中
第三步,在每个线程的任意执行位置,都可以通过该线程私有的TLS索引数组的相应条目,使用TlsGetValue()函数得到上一步的那块内存区域的地址,然后就可以对该内存区域做读写操作了。这就实现了在一个线程内部处处可访问的线程局部存储。
最后,如果不再需要上述线程局部静态变量,要动态释放掉这块内存区域(使用LocalFree()函数),这一般在线程即将结束时清理线程占用的各项资源时释放。然后,主进程从TLS索引数组中放弃对应的条目的占用(使用TlsFree()函数)