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

static线程安全

在 C++ 中,静态变量(static variables) 在多线程环境下需要特别注意 线程安全,因为它们被所有线程共享。以下是不同场景下的使用示例及最佳实践:

1. 全局静态变量(线程安全需加锁)

#include <iostream>
#include <thread>
#include <mutex>// 全局静态变量(所有线程共享)
static int sharedCounter = 0; // 所有线程共享的静态变量
static std::mutex mtx;  // 互斥锁保护共享变量void incrementCounter() {for (int i = 0; i < 1000; ++i) {std::lock_guard<std::mutex> lock(mtx);  // 在构造时锁定 mtx,析构时自动解锁(即使发生异常也会解锁)。sharedCounter++;   // 安全修改} //作用域结束时(}),lock 对象析构,释放锁。
}int main() {std::thread t1(incrementCounter); // 启动线程1std::thread t2(incrementCounter); // 启动线程2t1.join(); // 等待线程1结束t2.join();// 等待线程2结束std::cout << "Final counter value: " << sharedCounter << std::endl;  // 应为 2000return 0;
}

在这里插入图片描述
在这里插入图片描述
关键点:

使用 std::mutex 保护共享静态变量,避免竞态条件。

std::lock_guard 在作用域结束时自动释放锁。

2. 局部静态变量(延迟初始化需线程安全)

如果静态变量在函数内部(需要延迟初始化),C++11 起保证其初始化是线程安全的:

#include <iostream>
#include <thread>void initStaticVar() {static int lazyInitialized = 42;  // C++11 起线程安全初始化std::cout << "Value: " << lazyInitialized << std::endl;
}int main() {std::thread t1(initStaticVar);std::thread t2(initStaticVar);t1.join();t2.join();return 0;
}

注意:

C++11 前需手动加锁(如 pthread_once)。

修改 lazyInitialized 仍需额外同步。

3. 静态类成员变量(需外部定义)

#include <iostream>
#include <thread>
#include <mutex>class MyClass {
public:static int classVar;  // 声明static std::mutex mtx;static void modifyClassVar() {std::lock_guard<std::mutex> lock(mtx);classVar++;}
};// 必须在类外定义静态成员
int MyClass::classVar = 0;
std::mutex MyClass::mtx;int main() {std::thread t1(&MyClass::modifyClassVar);std::thread t2(&MyClass::modifyClassVar);t1.join();t2.join();std::cout << "Final classVar: " << MyClass::classVar << std::endl;  // 应为 2return 0;
}

规则:

静态类成员需在类外单独定义(链接器需要实际存储)。

修改时同样需要加锁。

4. 线程局部静态变量(C++11 thread_local)

如果希望每个线程有独立的静态变量副本:

#include <iostream>
#include <thread>void threadLocalStatic() {thread_local static int localCounter = 0;  // 每个线程独立localCounter++;std::cout << "Thread " << std::this_thread::get_id() << ", localCounter: " << localCounter << std::endl;
}int main() {std::thread t1([](){threadLocalStatic();threadLocalStatic();  // 输出 1, 2});std::thread t2([](){threadLocalStatic();  // 输出 1});t1.join();t2.join();return 0;
}

5. 最佳实践总结

在这里插入图片描述

http://www.lqws.cn/news/580411.html

相关文章:

  • 10.【C语言学习笔记】指针(二)
  • 汉字田(第十五届蓝桥杯大赛软件赛国赛)
  • 生成式人工智能实战 | 变分自编码器(Variational Auto-Encoder, VAE)
  • zxing-cpp c++版本的编译
  • 【T2I】RB: REGION AND BOUNDARY AWARE ZERO-SHOT GROUNDED TEXT-TO-IMAGE GENERATION
  • RK3588高性能处理器核心技术解析
  • 从0开始学习计算机视觉--Day06--反向传播算法
  • chatshare最新激活码分享
  • OpenCV计算机视觉实战(14)——直方图均衡化
  • Windows环境下Docker容器化的安装与设置指南
  • MySQL DATETIME 类型时间精度陷阱:一次由毫秒引发的数据“消失”之谜
  • 计算机网络第一章——计算机网络体系结构
  • Pandas5(数据清洗1)——缺失值处理、数据去重/转换/替换、离散化/分箱、检测和过滤异常值
  • 【Kafka】docker 中配置带 Kerberos 认证的 Kafka 环境(全过程)
  • NIO 工作原理
  • C++ cstring 库解析:C 风格字符串函数
  • 【甲方安全建设】SDL基线建设及审计评估
  • API接口安全-2:签名、时间戳与Token如何联手抵御攻击
  • 【第二章:机器学习与神经网络概述】04.回归算法理论与实践 -(1)线性回归模型
  • Web攻防-SSRF服务端伪造功能逻辑SRC实践复盘参数盲测自动化检测流量插件
  • 【ArcGISPro】解决Pro不能导入AppData下的site-packages
  • MySQL数据库--SQL DDL语句
  • 大学专业科普 | 云计算、大数据
  • 淘宝API接口在数据分析中的应用
  • [springboot系列] 探秘 JUnit 5:现代 Java 单元测试利器
  • 2025年数据治理平台排名及功能对比分析
  • Nacos 3.0 架构全景解读,AI 时代服务注册中心的演进
  • 通过案列理解js中的深拷贝和浅拷贝
  • Server-Sent Events (SSE) 技术详解
  • 【原创】【5】【视频二创工具发布】基于视觉模型+FFmpeg+MoviePy实现短视频自动化二次编辑+多赛道