C++11 thread_local 关键词

版权声明:本文为博主原创文章,未经博主允许不得转载。博客主页:http://blog.csdn.net/u013390476 https://blog.csdn.net/u013390476/article/details/52129607

前言

在C++11多线程编程中,thread_local 这个关键词在一些特定场合挺有用的。什么是thread_local关于thread_local

thread_specific_ptr代表了一个全局的变量,而在每个线程中都各自new一个线程本地的对象交给它进行管理,这样,各个线程就可以各自独立地访问这个全局变量的本地存储版本,线程之间就不会因为访问同一全局对象而引起资源竞争导致性能下降。而线程结束时,这个资源会被自动释放。
C++11的thread_local来自于boost中的thread_specific_ptr


thread_local使用场景

dre是一个全局的default_random_engine对象(全局对象可以是C风格的extern,也可是C++风格的static,如果在同一个源文件中,则在“代码的上面”)。同时开启多个线程运行,每个线程都需要使用这个全局的dre对象,不同的线程对dre设置不同的seed。但是,又不能让所有线程同时访问同一个dre,这样dre的seed变来变去,而且无法得到想要的随机值序列。

此时有2个解决方案:

  1. 改变声明dre的地方,把dre从全局对象变为线程的局部变量(比如一个函数中)。在线程里面,再通过参数的传递,把dre传到需要它的地方。
  2. 声明dre的地方不变,依然是全局,只要加一个thread_local关键词,其他什么都不用改。

方案1很丑陋,方案2很优雅。


talk is cheap, show me the code

#include <iostream>
#include <future>
#include <vector>
#include <chrono>
#include <random>
using namespace std;
using namespace chrono;

thread_local default_random_engine dre;

vector<int> test_dre(int seed)
{
    dre.seed(seed);
    int vecSize = 10;
    vector<int> temp(vecSize);
    for (int i = 0; i < vecSize; ++i)
    {
        temp[i] = dre();
        this_thread::sleep_for(milliseconds(100));
    }
    return temp;
}

bool equal(const vector<int> &v1, const vector<int> &v2)
{
    int size1 = v1.size();
    int size2 = v2.size();
    if (size1 != size2)
        return false;

    for (int i = 0; i < size1; ++i)
    {
        if (v1[i] != v2[i])
            return false;
    }
    return true;
}

int main()
{
    int numThread = 2;
    using returnType = vector<int>;

    future<returnType> future1 = async(test_dre, 0);
    returnType result2 = test_dre(0);
    returnType result1 = future1.get();

    if (equal(result1, result2))
        cout << "they are equal" << endl;
    else
        cout << "they are not equal" << endl;

    system("pause");
    return 0;
}

程序运行结果:

they are equal

分析:两个线程运行的时候,拥有不同的dre。但是写代码的时候,却是相同的dre。这就很爽了!

如果把thread_local这个关键词注释掉,那么两个线程就会发生data race。运行结果是:

they are not equal

猜你喜欢

转载自blog.csdn.net/u013390476/article/details/52129607