美文网首页
线程局部存储

线程局部存储

作者: ColdWave | 来源:发表于2018-08-18 23:36 被阅读0次

    线程局部存储

    线程局部存储(TLS,thread local storage) 就是拥有线程生命周期及线程可见性的变量。

    线程局部存储实际上是由单线程程序中的全局/静态变量被应用到多线程程序中被线程共享而来。我们可以简单地回顾一下所谓的线程模型。通常情况下,线程会拥有自己的栈空间,但是堆空间、静态数据区则是共享的。这样一来,全局、静态变量在这种多线程模型下总是再线程间共享的。

    全局,静态变量的共享会带来好处,但是并不是所有的全局,静态变量适合在在多线程的情况下共享。

    #include <pthread.h>
    #include <iostream>
    
    int errorCode = 0;
    
    void* MaySetErr(void* input)
    {
        if (*(int *)input == 1)
            errorCode = 1;
        else if (*(int *)input == 2)
            errorCode = -1;
        else
            errorCode = 0;
    }
    
    int main()
    {
        int input_a = 1;
        int input_b = 2;
    
        pthread_t thread1, thread2;
    
        pthread_create(&thread1, NULL, &MaySetErr, &input_a);
        pthread_create(&thread2, NULL, &MaySetErr, &input_b);
    
        pthread_join(thread2, NULL);
        pthread_join(thread1, NULL);
    
        std::cout << errorCode << std::endl;
    
        return 0;
    }
    

    errorCode 值无法确定。因为 线程1 和 线程2 的执行顺序是无法确定的。
    实际上,本例中 errorCode 即是 POSIX 标准中的错误全局变量 errno 在多线程情况下遇到问题的一个简化。
    一旦 errno 在线程间共享时,则一些程序中允许的错误将会被隐藏不报。而解决方法就是为每个线程指派一个全局的 errno,即 TLS 化 的 errno。

    不同的编译器有不同的 TLS 标准。

    g++/clang++/xlc++ 可以看到如下语法:

    __thread int errCode;
    

    每个线程拥有独立的 errCode 的拷贝,一个线程中的 errCode 的读写并不会影响另一个线程中的 errCode。

    C++11 对 TLS 标准做了统一的规定。

    int thread_local errCode;
    

    对 thread_local 变量地址取值(&),也只能获得当前现场中 TLS 变量的地址值。

    相关文章

      网友评论

          本文标题:线程局部存储

          本文链接:https://www.haomeiwen.com/subject/otpqiftx.html