C库使用多线程的实现使用了TSL技术(线程本地储存)

问题

  1. C库函数使用多线程会出现问题,因为C语言比多线程出现的早,那时候的函数没有考虑多线程的问题

解决办法

  1. 换C库的多线程dll、lib

  2. 用_beginthreadex创建线程

测试代码

HANDLE hThread = (HANDLE)_beginthreadex(NULL,
                                   0,
                                   (unsigned (__stdcall *) (void *))ThreadFunc, 
                                   (LPVOID)dwIndex, 
                                   0,
                                   NULL);

TLS

  • C库使用多线程的实现使用了TSL技术(线程本地储存)
    大体思路是把全局变量都放入一个结构体中,每一个线程都有单独的一个结构体。

实现是建立一个表:

a2998a09-5b6b-4c4e-85cf-81c122641b5a.png

TlsAlloc 函数

DWORD WINAPI TlsAlloc(void);

(1)系统对进程中的位标志进行检索并找到一个FREE标志。

(2)然后系统会将该标志从FREE改为INUSE并让TlsAlloc返回该标志在位数组中的索引。

TlsSetValue 函数
设置变量值

BOOL WINAPI TlsSetValue (DWORD dwTlsIndex, LPVOID lpTlsValue);

参数:

dwTlsIndex: 索引值,表示在数组中的具体位置

lpTlsValue: 要设置的值

TlsGetValue 函数
获取变量值
LPVOID WINAPI TlsGetValue(DWORD dwTlsIndex);
参数:

dwTlsIndex : 索引值,表示在数组中的具体位置。

返回:
返回在索引为deTlsIndex的TLS元素中保存的值为TlsGetValue只会查看属于调用线程的数组。

TlsFree 函数

BOOL WINAPI TlsFree(DWORD dwTlsindex);

参数:
dwTlslndex : 索引值,表示在数组中的具体位置。
返回:

成功:true
失败:false

测试代码
void TestTls(int dwIndex);
DWORD ThreadFunc(LPVOID lpParam){
  TestTls((int)lpParam);
  return 0;
}
void TestTls(int dwIndex){
  DWORD error_no = 0;
  TlsSetValue(dwIndex, &error_no);
  LPVOID lp = TlsGetValue(dwIndex);
}
int main(int argc, char* argv[])
{
  DWORD dwIndex = TlsAlloc();
  DWORD error_no = 0;
  TlsSetValue(dwIndex, &error_no);
  LPVOID lp = TlsGetValue(dwIndex);
   HANDLE hThread = (HANDLE)_beginthreadex(NULL,
                                   0,
                                   (unsigned (__stdcall *) (void *))ThreadFunc, 
                                   (LPVOID)dwIndex, 
                                   0,
                                   NULL);
   WaitForSingleObject(hThread, INFINITE);
  return 0;
}


转载请说明出处
草堂教程网 » C库使用多线程的实现使用了TSL技术(线程本地储存)

发表评论

欢迎 访客 发表评论

一个纯粹的精品教程收录分享站点

查看演示 官网购买