c++11: thread_local
thread_local变量是C++ 11新引入的一种存储类型。它会影响变量的存储周期(Storage duration),C++中有4种存储周期:
- automatic
- static
- dynamic
- thread
有且只有thread_local关键字修饰的变量具有线程周期(thread duration),这些变量(或者说对象)在线程开始的时候被生成(allocated),在线程结束的时候被销毁(deallocated)。并且每 一个线程都拥有一个独立的变量实例(Each thread has its own instance of the object)。thread_local 可以和static 与 extern关键字联合使用,这将影响变量的链接属性(to adjust linkage)。
那么,哪些变量可以被声明为thread_local?以下3类都是ok的
- 命名空间下的全局变量
- 类的static成员变量
- 本地变量
下面引用《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个问题需要考虑:
- 各线程的thread_local变量是如何初始化的
- 各线程的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 = 1; void f()
{
g_n++;
printf("id=%d, n=%d\n", std::this_thread::get_id(),g_n);
} void foo()
{
thread_local int i=0;
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 0;
}
输出(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
c++11: thread_local的更多相关文章
- C++ 11学习和掌握 ——《深入理解C++ 11:C++11新特性解析和应用》读书笔记(一)
因为偶然的机会,在图书馆看到<深入理解C++ 11:C++11新特性解析和应用>这本书,大致扫下,受益匪浅,就果断借出来,对于其中的部分内容进行详读并亲自编程测试相关代码,也就有了整理写出 ...
- 《剑指offer》面试题11: 数值的整数次方
面试题11: 数值的整数次方 剑指offer面试题11,题目如下 实现函数double power(double base,int exponent),求base的exponent次方, 不得使用库 ...
- 开发错误11:Configuration with name ‘default’ not found
开发错误11:Configuration with name 'default' not found 今天在导入一个sdkdemoapp3.0项目时,发现project build.gradle 与m ...
- Ext.Net学习笔记11:Ext.Net GridPanel的用法
Ext.Net学习笔记11:Ext.Net GridPanel的用法 GridPanel是用来显示数据的表格,与ASP.NET中的GridView类似. GridPanel用法 直接看代码: < ...
- 【译】ASP.NET MVC 5 教程 - 11:Details 和 Delete 方法详解
原文:[译]ASP.NET MVC 5 教程 - 11:Details 和 Delete 方法详解 在教程的这一部分,我们将研究一下自动生成的 Details 和Delete 方法. Details ...
- PHP 11:函数
原文:PHP 11:函数 本文章介绍PHP的函数.如何学习呢?可以从以下几个方面考虑 函数是如何定义的?区分大小写吗? 函数的参数是如何定义的? 函数是否支持重载? 函数的返回值是如何定义的. 函数有 ...
- Bootstrap入门(十七)组件11:分页与标签
Bootstrap入门(十七)组件11:分页与标签 1.默认样式的分页 2.分页的大小 3.禁用的分页 4.翻页的效果 5.两端对齐的分页 6. 标签的不同样式 7. 标签的大小 先引入本地的 ...
- Oracle12c 性能优化攻略:攻略1-1:创建具有最优性能的数据库
一:章节前言 本章着眼于影响表中数据存储性能的数据库特性. 表的性能部分取决于在创建之前所应用的数据库特性.例如:在最初创建数据库时采用的物理存储特性以及相关的表空间都会在后来影响表的性能.类似地,表 ...
- 《深入应用C++11:代码优化与工程级应用》勘误表
<深入应用C++11:代码优化与工程级应用>勘误表,会不断更新,欢迎读者留言或发邮件(cpp11book@163.com)给我提出宝贵意见. 1.第7.3节目录final和override ...
随机推荐
- javascript 跨域问题解决办法总结
跨域的意思就是不同域名之间的页面默认是无法通信的.因为浏览器默认是禁止跨域的: 图所示:chrome浏览器尝试获取mainFrame失败,提示DomException 1).假如你有个网站 a.com ...
- 删除rime输入法
mac: 首先将输入法从偏好设置-键盘-输入源中去除,添加系统的输入法. 然后执行命令: $ killall Squirrel $ sudo rm -Rf "/Library/Input M ...
- mpv 播放器
https://mpv.io/ Mac版本: 官网: https://mpv.io/ https://mpv.io/installation/ 下载: http://sva.wakku.to/~chr ...
- zoj 3965 Binary Tree Restoring(搜索)
Binary Tree Restoring Time Limit: 1 Second Memory Limit: 65536 KB Special Judge Given two ...
- VMware设置NAT网络及 CentOS 7IP配置
1.打开VMware,选择 编辑, 虚拟网络编辑器 2.默认情况下,VMware8为我们NAT所使用的网卡,选中VMnet8 3.此处设置我们的IP地址,这个随便指定,我这里设置成192.168.2 ...
- MongoDB shell基本操作
shell命令操作语法和JavaScript很类似,其实控制台底层的查询语句都是用JavaScript脚本完成操作的.使用shell 命令,需要启动mongo.exe.mongodb百科 常用shel ...
- Linux 修改PostgreSQL外部访问白名单
1. 查找配置文件 # find / -name pg_hba.conf # find / -name postgresql.conf 2.修改 2.1 修改pg_hba.conf 查找IPv4 lo ...
- Js里头的对象字面量
JavaScript 对象字面量 在编程语言中,字面量是一种表示值的记法.例如,"Hello, World!" 在许多语言中都表示一个字符串字面量(string literal ) ...
- linux内核图形配置疑难解决
配置linux内核是遇到的问题:(1)问题一make gconfig * * Unable to find the GTK+ installation. Please make sure that * ...
- hdu 3932 Groundhog Build Home——模拟退火
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3932 注意平均值与最远的点距离为0的情况.所以初值设成-1,这样 id 就不会乱.不过设成0也可以.注意判 ...