thread_local变量是C++ 11新引入的一种存储类型。它会影响变量的存储周期(Storage duration),C++中有4种存储周期:

  1. automatic
  2. static
  3. dynamic
  4. thread

有且只有thread_local关键字修饰的变量具有线程周期(thread duration),这些变量(或者说对象)在线程开始的时候被生成(allocated),在线程结束的时候被销毁(deallocated)。并且每 一个线程都拥有一个独立的变量实例(Each thread has its own instance of the object)。thread_local 可以和staticextern关键字联合使用,这将影响变量的链接属性(to adjust linkage)。

那么,哪些变量可以被声明为thread_local?以下3类都是ok的

  1. 命名空间下的全局变量
  2. 类的static成员变量
  3. 本地变量

下面引用《C++ Concurrency in Action》书中的例子来说明这3种情况:

thread_local int x;  //A thread-local variable at namespace scope
class X
{
    static thread_local std::string s; //A thread-local static class data member
};
static thread_local std::string X::s;  //The definition of X::s is required void foo()
{
    thread_local std::vector<int> v;  //A thread-local local variable
}

既然每个线程都拥有一份独立的thread_local变量,那么就有2个问题需要考虑:

  1. 各线程的thread_local变量是如何初始化的
  2. 各线程的thread_local变量在初始化之后拥有怎样的生命周期,特别是被声明为thread_local的本地变量(local variables)

下面的代码可以帮助回答这2个问题,我的测试环境是vs2015。

输出的前3行打印能帮助解答thread_local变量是如何初始化的,可以看到每个线程都会进行一次初始化,例子中的g_n在主线程中最早被初始化为1,随后被修改为2和3,但这些修改操作并不影响g_n在线程t2和t3中的初始值(值为1),虽然t2和t3线程启动的时候主线程中的变量值已经被更新为3,所以主线程、thread1、thread2打印结果分别为3,2,2。

后6行打印说明了一个事实,声明为thread_local的本地变量在线程中是持续存在的,不同于普通临时变量的生命周期,它具有static变量一样的初始化特征和生命周期,虽然它并没有被声明为static。例子中foo函数中的thread_local变量 i 在每个线程第一次执行到的时候初始化,在每个线程各自累加,在线程结束时释放。

#include <thread>

thread_local int g_n = ;

void f()
{
    g_n++;
    printf("id=%d, n=%d\n", std::this_thread::get_id(),g_n);
} void foo()
{
    thread_local int i=;
    printf("id=%d, n=%d\n", std::this_thread::get_id(), i);
    i++;
} void f2()
{
    foo();
    foo();
} int main()
{
    g_n++; 
    f();    
    std::thread t1(f);
    std::thread t2(f);
    
    t1.join();
    t2.join();     f2();
    std::thread t4(f2);
    std::thread t5(f2);     t4.join();
    t5.join();
    return ;
}

输出(id值是每次运行时变的):

id=8004, n=3

id=8008, n=2
id=8012, n=2
id=8004, n=0
id=8004, n=1
id=8016, n=0
id=8016, n=1
id=8020, n=0
id=8020, n=1

thread_local变量的更多相关文章

  1. thread_local变量(转)

    转自:https://www.cnblogs.com/pop-lar/p/5123014.html thread_local变量是C++11新引入的一种存储类型.它会影响变量的存储周期(Storage ...

  2. c/c++ 多线程 thread_local 类型

    多线程 thread_local 类型 thread_local变量是C++ 11新引入的一种存储类型. thread_local关键字修饰的变量具有线程周期(thread duration), 这些 ...

  3. c++11: thread_local

    thread_local变量是C++ 11新引入的一种存储类型.它会影响变量的存储周期(Storage duration),C++中有4种存储周期: automatic static dynamic ...

  4. [c++] Pieces of knowledge

    再系统地学一遍c++,查缺补漏. wchar_t L'a' stored in wchar_t. size of types cout << numeric_limits<doubl ...

  5. C++14介绍

    C++14标准是 ISO/IEC 14882:2014 Information technology -- Programming languages -- C++ 的简称[1]  .在标准正式通过之 ...

  6. C++11 (多线程)并发编程总结

    | 线程 std::thread 创建std::thread,一般会绑定一个底层的线程.若该thread还绑定好函数对象,则即刻将该函数运行于thread的底层线程. 线程相关的很多默认是move语义 ...

  7. Linux 调试: systemtap

    安装与配置 在ubuntu下直接用apt-get install之后不能正常使用,提示缺少调试信息或者编译探测代码时有问题. 1. 采用官网上的解决方法 2. 可以自己重新编译一次内核,然后再手工编译 ...

  8. C++11并发编程个人小结

    thread_local变量在每个线程第一次执行到时初始化(类似static),并在每个线程各自累加,并在线程结束时释放. std::condition_variable:: wait(std::un ...

  9. C++的各种初始化方式

    C++小实验测试:下面程序中main函数里a.a和b.b的输出值是多少? #include <iostream> struct foo { foo() = default; int a; ...

随机推荐

  1. angular2-scroll-module

    这篇介绍一下,写一个自己的angular2滚动监听插件 目录结构: /scrollModule: ztw-scroll.module.ts; scrollBind.directive.ts; scro ...

  2. Java小程序之回文数字

    题目:一个5位数,判断它是不是回文数.即12321是回文数,个位与万位相同,十位与千位相同. 下面是代码: package test; public class BackNum { public st ...

  3. ubuntu16.04 运行elasticfusion

    环境:Ubuntu16.04 64bit    Kinect V1 XBOX 360 1.安装OpenNI2并试运行 https://fredfire1.wordpress.com/2016/09/2 ...

  4. linux中的kill命令

    一. 定义 kill命令用来删除执行中的程序或工作.kill可将指定的信息送至程序.预设的信息为SIGTERM(15),可将指定程序终止.若仍无法终止该程序,可使用SIGKILL(9)信息尝试强制删除 ...

  5. LinuxMint Mate 安装Google拼音输入法(Fcitx)

    安装Google拼音输入法(Fcitx)$ sudo apt-get install fcitx fcitx-config-gtk fcitx-frontend-all fcitx-ui-classi ...

  6. 51nod 1406 位运算/dp

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1406 1406 与查询 题目来源: CodeForces 基准时间限制: ...

  7. Node——用http-proxy 做反向代理服务器

    时下不少场景,都是申请一个 VPS 主机来托管运行 Web 项目的,小弟我也不例外——购买了一个小型的 CentOS VPS 使用着.在使用的过程中,面临一个问题,就是同一类型的服务端环境还好——但如 ...

  8. WCF基础:绑定(二)

    在WCF的绑定体系中,经常会碰到ICommunicationObject接口,无论是IChannel接口还是IChannelListener/IChannelFactory接口都继承了ICommuni ...

  9. LeetCode OJ:Best Time to Buy and Sell Stock(股票买卖的最佳时期)

    Say you have an array for which the ith element is the price of a given stock on day i. If you were ...

  10. Manual Install Cocos2d-x vc template on Windows 7

    Manual Installation Process Download the template file from HERE and extract it. Open the file CCApp ...