线程局部存储(TLS)

线程局部存储区(Thread Local Storage, TLS):将数据与一个正在执行的特定函数关联起来。

 

线程局部存储是将现有函数变为线程安全的有用技巧。

当一个函数中访问并修改全局或静态变量,那么这个函数就是不可重入的。若使之变为可重入的函数,可以使用线程同步,也可以使用线程局部存储。线程局部存储为每一个访问此变量的线程提供一个此变量独立的副本,线程可以修改此变量,而不会影响到其他线程。

:通过以上描述可以看出,线程局部存储不是用来共享变量的。

 

C标准库中的strtok就是一个典型的不可重入函数。当程序第一次调用它时,该函数会将传入的字符串地址保存在它自己的静态变量中;当再次调用strtok并传入NULL时,该函数会自动引用保存下来的字符串地址。

 

想一想,如果一个线程正在使用strtok的时候,另外一个线程也调用此函数,那就会产生很大的问题,第一个线程传入的字符串被替换掉了!为了解决这种问题,C/C++运行库使用了TLS

 

Windows中应用TLS的一个简单示例:计算线程的运行时间

  1 //

 2  #include <windows.h>
 3 #include <process.h>
 4 
 5 #include <ctime>
 6 #include <cstdlib>
 7 #include <vector>
 8 #include <iostream>
 9 
10  using  namespace std;
11 
12 unsigned  int __stdcall threadProc( void *arg)
13 {
14     DWORD tlsIndex = reinterpret_cast<DWORD>(arg);
15     clock_t begin = clock();
16     TlsSetValue(tlsIndex, PVOID(begin) );   //  利用TlsSetValue 设置 值
17 
18     printf( " \nbegin thread: %d, clock_t: %d ", GetCurrentThreadId() , begin);
19 
20     Sleep( 3000);
21 
22     clock_t end = clock();
23     clock_t diff = end -  reinterpret_cast<clock_t>(TlsGetValue(tlsIndex) );
24      double sec =  1.0 * diff / CLOCKS_PER_SEC;  //  利用TlsGetValue取得值
25 
26     printf( " \nend thread: %d, clock: %d, live time %f ", GetCurrentThreadId(), end, sec );
27 
28      return  0;
29 }
30 
31  int main( int argc,  char *argv[])
32 {
33      //  分配Tls索引
34      DWORD tlsIndex = TlsAlloc();
35 
36     vector<HANDLE> threads;
37      for ( int i =  0; i <  50; ++i){
38         HANDLE h = (HANDLE)_beginthreadex(NULL,  0, threadProc, ( void*)tlsIndex,  0, NULL);
39         threads.push_back(h);
40     }
41 
42      for (size_t i =  0; i < threads.size(); ++i){
43         WaitForSingleObject(threads[i], INFINITE);
44         CloseHandle(threads[i]);
45     }
46 }
47  //

 

 

转载于:https://www.cnblogs.com/hdtianfu/archive/2012/10/18/2730282.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值