当前位置: 首页 > news >正文

C/C++ 线程局部存储(TLS)

在C或C++中,线程局部存储(Thread-Local Storage,简称TLS)是一种用于存储线程特有数据的方法。这意味着每个线程都可以访问它自己的变量实例,而不会影响到其他线程中的同名变量。这在多线程程序中非常有用,因为它可以避免对共享数据的竞争和同步开销。

C++11引入了thread_local关键字来简化线程局部存储的使用。在C中,则需要依赖操作系统或编译器提供的特定机制,如GCC的__thread关键字。

C++11中的thread_local示例

下面是一个C++11中使用thread_local的简单例子:

#include <iostream>
#include <thread>
#include <vector>// 定义一个线程局部的整型变量
thread_local int tls_counter = 0;void increment_counter() {tls_counter++; // 每个线程都会独立地增加自己的tls_counterstd::cout << "Thread " << std::this_thread::get_id() << " incremented tls_counter to " << tls_counter << std::endl;
}int main() {std::vector<std::thread> threads;// 创建10个线程for (int i = 0; i < 10; ++i) {threads.emplace_back(increment_counter);}// 等待所有线程完成for (auto& th : threads) {th.join();}return 0;
}

输出:

Thread 140517560022592 incremented tls_counter to 1
Thread 140517551629888 incremented tls_counter to 1
Thread 140517534844480 incremented tls_counter to 1
Thread 140517543237184 incremented tls_counter to 1
Thread 140517409019456 incremented tls_counter to 1
Thread 140517526451776 incremented tls_counter to 1
Thread 140517518059072 incremented tls_counter to 1
Thread 140517438387776 incremented tls_counter to 1
Thread 140517429995072 incremented tls_counter to 1
Thread 140517421602368 incremented tls_counter to 1

在这个例子中,tls_counter是一个线程局部变量,每个线程都会拥有自己的tls_counter实例。因此,尽管所有线程都调用了increment_counter函数,但每个线程都会独立地增加自己的tls_counter,而不会影响到其他线程的tls_counter

GCC的__thread在C中的示例

对于C语言,可以使用GCC的__thread关键字来实现类似的功能:

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>// 定义一个线程局部的整型变量
__thread int tls_counter = 0;void* increment_counter(void* arg) {tls_counter++; // 每个线程都会独立地增加自己的tls_counterprintf("Thread %ld incremented tls_counter to %d\n", (long)pthread_self(), tls_counter);return NULL;
}int main() {pthread_t threads[10];// 创建10个线程for (int i = 0; i < 10; ++i) {pthread_create(&threads[i], NULL, increment_counter, NULL);}// 等待所有线程完成for (int i = 0; i < 10; ++i) {pthread_join(threads[i], NULL);}return 0;
}
Thread 127565616375360 incremented tls_counter to 1
Thread 127565599589952 incremented tls_counter to 1
Thread 127565624768064 incremented tls_counter to 1
Thread 127565582804544 incremented tls_counter to 1
Thread 127565607982656 incremented tls_counter to 1
Thread 127565591197248 incremented tls_counter to 1
Thread 127565574411840 incremented tls_counter to 1
Thread 127565477959232 incremented tls_counter to 1
Thread 127565486351936 incremented tls_counter to 1
Thread 127565494744640 incremented tls_counter to 1

这个例子与C++的例子类似,但使用了C的pthread库来创建和管理线程,并使用__thread关键字来声明线程局部变量。

注意,虽然__thread在GCC中非常有用,但它并不是C语言标准的一部分,因此在使用时需要考虑跨平台兼容性问题。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • vue3+vite配置环境变量实现开发、测试、生产的区分
  • 利用Matlab求解常微分方程(dsolve与ode45)
  • easypoi模板导出word并且合并行
  • Error connecting to node kafka9092 (id 1001 rack null)
  • 工厂模式和策略模式的区别
  • TCP系列相关内容
  • AI作曲工具真的这么神奇?新手也能出音乐!
  • 多指标用于评估文本生成模型的性能
  • zdppy+vue3+onlyoffice文档管理系统实战 20240823上课笔记 zdppy_cache框架的低代码实现
  • 计量自动化终端上行通信规约
  • Vue3 自定义指令
  • 【网络安全】服务基础第一阶段——第二节:网络测试与用户
  • 学习记录:js算法(十三):移动零、验证回文串
  • 考研备考是选择电子学习工具无纸化学习?还是纸质版训练考感?
  • 《javaEE篇》--线程池
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 0x05 Python数据分析,Anaconda八斩刀
  • Android Volley源码解析
  • Android开源项目规范总结
  • C++11: atomic 头文件
  • Java|序列化异常StreamCorruptedException的解决方法
  • Java程序员幽默爆笑锦集
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • Nodejs和JavaWeb协助开发
  • Python语法速览与机器学习开发环境搭建
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • Spring Cloud中负载均衡器概览
  • vue-router的history模式发布配置
  • 开源SQL-on-Hadoop系统一览
  • 树莓派 - 使用须知
  • 数组的操作
  • No resource identifier found for attribute,RxJava之zip操作符
  • const的用法,特别是用在函数前面与后面的区别
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • 湖北分布式智能数据采集方法有哪些?
  • 容器镜像
  • 我们雇佣了一只大猴子...
  • # linux 中使用 visudo 命令,怎么保存退出?
  • #知识分享#笔记#学习方法
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • $forceUpdate()函数
  • $LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams
  • (7)摄像机和云台
  • (每日一问)操作系统:常见的 Linux 指令详解
  • (算法)N皇后问题
  • (一) 初入MySQL 【认识和部署】
  • (转)母版页和相对路径
  • .bat批处理(十):从路径字符串中截取盘符、文件名、后缀名等信息
  • .equals()到底是什么意思?
  • .md即markdown文件的基本常用编写语法
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions
  • .NET建议使用的大小写命名原则
  • .net最好用的JSON类Newtonsoft.Json获取多级数据SelectToken
  • /etc/shadow字段详解