C++11的thread_local原理和应用范例

前言

在内存模型之上,C++提供了线程加锁的并发模型来消除数据竞争(比如全局数据。数据竞争可能产生极为隐晦的并发错误)。但是,线程加锁级别的并发是应用程序使用并发的比较差的模型。

C++11引入了thread_local来保证线程访问全局数据的安全,thread_local告诉线程进行数据本地存储(线程本地存储一个数据备份),从而消除线程间数据竞争的一种方式。

thread_local概念

thread_local是C++11引入的新特性,是一个关键字,用于修饰变量(thread_local关键字和static、extern关键字在使用上是不冲突的),告诉线程对此关键词修饰的数据进行本地存储。

使用的头文件:#include< thread>

thread_local与“线程加锁”的区别

thread_local:把全局数据拷贝出一份自己使用,从进程内部所有线程共用变成线程内部私有。随后线程使用的变量就是这个备份数据,不再关心原全局数据的数值。

(进程内部的数据在那里,只是系统给当前线程分配了同样类型同样名称的变量,专供本线程使用。)

线程加锁的方式:全局数据进程内部所有线程共用,每个线程都可以对这个数据进行读和写,为了保证数据同一时间只能有一个修改,所以加锁进行限制。

thread_local应用场景

为了防止变量值的不可预测性,保证各线程内变量值的互不干扰,想要达到线程内独有的全局变量的场合。

举例(仅供参考):

①修饰全局业务唯一性的某个全局变量A,在fun_A函数中进行A的赋值(比如,随机数、随机串、线程池个数等赋值计算)。

以前当前进行内部所有线程都共用A和fun_A,但是根据业务扩展需要,每个线程内部都需要维护一份业务唯一性数据。但是业务特殊性导致线程之间业务差异比较大,无法通过拷贝多个进程实现多种业务。

所以为了修改方便,可以选择对A的变量增加thread_local修饰的方案。

thread_local的使用范例

thread_local主要是用来修饰变量,修饰变量的种类有以下四种:

1)全局变量

2)局部变量

3)类对象

4)类成员变量

下面我们以全局变量和局部变量为例,来说明thread_local修饰变量的效果。

示例代码:

#include <iostream>
#include <thread>

int g_a = 10;
thread_local int g_b = 20;
static int g_c = 30;
thread_local static int g_d = 40;

void fun(const std::string& name)
{
    for (int i = 0; i < 3; ++i)
    {
        thread_local  int temp = 1;  //只在每个线程创建时初始化一次
        temp++;
        std
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值