__thread 关键字

1. 概述

1.1 __thread是GCC内置的线程局部存储设施。_thread变量每一个线程有一份独立实体,各个线程的值互不干扰。可以用来修饰那些带有全局性且值可能变,但是又不值得用全局变量保护的变量。
1.2 举例说明

__thread int count = 0;
int main()
{
    //创建线程A
    //创建线程B
    //此时A和B线程都有一个实体 count,二者并不相同
}

2. 使用举例

#include <iostream>
#include <pthread.h>
#include <unistd.h>

__thread int i = 0;

void* f1(void* arg)
{
    i++;
    printf("f1 i address %p val %d\n", &i, i);
}

void* f2(void* arg)
{
    i += 2;
    printf("f2 i address %p val %d\n", &i, i);
    
}

int main()
{
    pthread_t pid1, pid2;
    i += 3;
    pthread_create(&pid1, NULL, f1, NULL);
    pthread_create(&pid2, NULL, f2, NULL);
    pthread_join(pid1, NULL);
    pthread_join(pid2, NULL);
    printf("main i address %p val %d\n", &i, i);

    return 0;
}

结果:

注意,f1 和 f2 中的地址并不相同

3. 使用方式

3.1 主要下面三种

__thread int i;

extern __thread struct state s;

static __thread char *p;

3.2 注意事项

(1) __thread是GCC内置的线程局部存储设施
(2) 只能修饰POD类型(类似整型指针的标量,不带自定义的构造、拷贝、赋值、析构的类型,二进制内容可以任意复制memset,memcpy,且内容可以复原).
(3)不能修饰class类型,因为无法自动调用构造函数和析构函数.
(4)可以用于修饰全局变量,函数内的静态变量,不能修饰函数的局部变量或者class的普通成员变量,且__thread变量值只能初始化为编译器常量.

4. 补充

4.1 利用以下一组函数设置

int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
void *pthread_getspecific(pthread_key_t key);
int pthread_setspecific(pthread_key_t key, const void *value);

4.2 C++11 引入了线程存储期 符号: thread_local

5. 参考资料

5.1 https://gcc.gnu.org/onlinedocs/gcc-4.2.4/gcc/Thread_002dLocal.html
5.2 https://www.cnblogs.com/zhangzhang/archive/2013/01/06/2847570.html
5.3 https://zh.cppreference.com/w/cpp/language/storage_duration

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 按时间顺序写一篇关于男孩子们的文章吧。可能与爱情有关,可能与友谊有关,也有可能与厌恶有关(笑)。不管怎么样都是印在...
    权水阅读 3,904评论 0 1
  • 我于2017年12月03日参观了格罗宁根省的印刷博物馆,这个博物馆展出了用于印刷报纸书刊的工具,让我眼界大开。 走...
    英天阅读 1,677评论 0 0
  • 引言:冬雪久已未至,今早醒来雪树银花,还没看过雪后的江景,姑且往之。 我在塔上看风景, 风光无限心澄明。 冰河无语...
    易词斋主人阅读 4,198评论 38 29