惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

I
InfoQ
C
CERT Recently Published Vulnerability Notes
The Last Watchdog
The Last Watchdog
P
Proofpoint News Feed
D
Darknet – Hacking Tools, Hacker News & Cyber Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
GbyAI
GbyAI
T
Tenable Blog
博客园 - 三生石上(FineUI控件)
P
Privacy & Cybersecurity Law Blog
Simon Willison's Weblog
Simon Willison's Weblog
Jina AI
Jina AI
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Tor Project blog
博客园_首页
F
Fortinet All Blogs
博客园 - Franky
Latest news
Latest news
Last Week in AI
Last Week in AI
T
Threat Research - Cisco Blogs
Scott Helme
Scott Helme
L
LINUX DO - 热门话题
U
Unit 42
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Hugging Face - Blog
Hugging Face - Blog
D
Docker
Project Zero
Project Zero
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
MongoDB | Blog
MongoDB | Blog
F
Full Disclosure
D
DataBreaches.Net
Google DeepMind News
Google DeepMind News
Cisco Talos Blog
Cisco Talos Blog
Y
Y Combinator Blog
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
H
Help Net Security
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
月光博客
月光博客
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Blog — PlanetScale
Blog — PlanetScale
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
S
Schneier on Security
C
Cybersecurity and Infrastructure Security Agency CISA
P
Proofpoint News Feed
PCI Perspectives
PCI Perspectives
Cloudbric
Cloudbric
V
Visual Studio Blog
Recorded Future
Recorded Future
人人都是产品经理
人人都是产品经理

博客园 - PKICA

博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 rust线程-std::thread::park和unpark 配合Builder实现轻量级的线程挂起与唤醒 rust自定义线程属性std::thread::Builder rust线程 rust关联函数 rust高并发设计实践进阶 rust高并发设计实践 rust性能优化与安全边界 联合体union在rust和C语言中有什么区别 rust并发与异步编程 如何预防rust不良的代码设计总结 rust类型系统与零成本抽象 rust内存模型 告别大显存依赖!用 Rust 新一代深度学习框架 Burn 打造纯 CPU 文本分类推理引擎 rust类型系统标记 编译配置解答 git实用命令 rust底层设计理念值得注意的几个地方总结 rust可变引用作为函数参数的机理详解 Rust内存重解释transmute C与Rust类型映射 Rust FFI 安全抽象范式 rust延迟初始化原语 rust重借用机制与原理 rust参数传递模型 汇编语言语法详解 gdb汇编调试 gdb-pwndbg的安装与使用指南 gdb调试插件gef linux系统readelf命令使用指南 gcore转储进程内存 gdb查看命令 RGB与YUV颜色编码的区别 Rust原子类型 C++ STL求两个集合交集差集 gdb调试集锦 ubuntu24.0.4使用root用户登录 ubuntu24.0.4输入密码后跳回登录界面 AI内存压缩技术TurboQuant及存疑 ubuntu切换到指定内核版本 在没有顶级科技大佬直接背书的情况下deepseek为啥能够异军突起? HuggingFace和deepseek的关系 当前主流AI大模型 Rust写时克隆Cow系列2
C语言thread_local
PKICA · 2026-04-14 · via 博客园 - PKICA

C语言中的 thread_local(在C11标准中为 _Thread_local,通常建议使用 <threads.h> 中的 thread_local 宏)用于声明线程局部存储 (Thread-Local Storage, TLS) 变量。

这种变量在每个线程中都有一个独立的实例,线程之间互不干扰,即使它们共享同一个变量名,在多线程环境下使用它不仅是线程安全的,还避免了互斥锁带来的性能开销。

1. thread_local 的核心特性

  • 线程生存期: 变量在线程启动时生成,在线程结束时销毁。
  • 独立副本: 每个线程存取的是属于自己的副本。
  • 初始化: 不同于普通变量,线程局部变量的值在线程启动时被初始化。
  • 修饰限制: 只能用于全局变量、文件范围的静态变量或函数内部的静态变量。

2. 使用方法 (C11 标准)

C11 标准引入了 _Thread_local 关键字。通常引入 <threads.h> (如果编译器支持) 或在 C23 标准中直接使用 thread_local。 

#include <stdio.h>
#include <threads.h> // C11线程标准库

// 定义一个线程局部变量
thread_local int thread_specific_var = 0;

int main_thread_func(void* arg) {
    thread_specific_var = 10; // 当前线程修改
    printf("Thread %d: var = %d\n", (int)thrd_current(), thread_specific_var);
    return 0;
}

int main() {
    thrd_t t1, t2;
    // 启动两个线程
    thrd_create(&t1, main_thread_func, NULL);
    thrd_create(&t2, main_thread_func, NULL);
    
    // 等待线程结束
    thrd_join(t1, NULL);
    thrd_join(t2, NULL);

    return 0;
}

在上面的示例中,如果 thread_local 没有被定义,两个线程会共享 thread_specific_var 并产生冲突。使用了 thread_local 后,每个线程会打印出各自的 10,互不干扰。

3. 不同标准下的写法

  • C11 / C17: 使用 _Thread_local#include <threads.h> 后的 thread_local
  • C23 : 直接使用 thread_local
  • GCC/Clang 扩展: 使用 __thread 关键字(static __thread int var;),它更早期且实现效率较高。

4. 关键注意事项

  • 静态/全局修饰: 如果在块作用域(函数内部)使用,必须加上 staticextern
  • 性能开销: 线程局部变量的读取通常比全局变量稍慢,且随着线程数量增加,内存占用会增大。
  • 复杂析构函数: 如果线程局部变量需要复杂的析构函数(在C++中更常见),可能会在线程退出时导致意外的释放后使用(use-after-free)问题。
  • 与POSIX pthread_key 区别: thread_local 是一种语言层面的特性,使用起来更简单、更高效,不再需要像 pthread_key_create 那样处理 void* 指针和显式管理内存。

一般,“标准方式”和“编译器扩展方式”区别:

特性_Thread_local (C11)__thread (GNU/Clang)
定义标准 C11 标准关键字 GCC/Clang 编译器扩展
引入方式 包含 <threads.h> 后可用 thread_local 宏 原生支持,无需头文件
约束限制 仅能用于全局或 static 变量 同左
初始化 只能用常量表达式初始化 只能用常量表达式初始化
性能 理论一致 在老版本 GCC 上可能略快

总结

在多线程程序中,如果需要维护线程特有的状态(如错误码 errno、特定线程的日志缓存等),thread_local 是现代C语言(C11及以后)推荐的线程安全实现方式。

参考资料: