C++中shared_ptr线程安全问题与constexpr关键字作用
1.shared_ptr线程安全问题
1.1.多线程多对象指向一个shared_ptr导致的线程不安全
- 例子:创建了10个线程,每个线程调用 ThreadFunc()函数。ThreadFunc()函数将g_instance std::shared_ptr对象的值增加10000次。main()函数然后休眠5000毫秒,这给了线程执行的时间。线程执行完毕后,main())函数将打印g_instance(std::shared_ptr对象)的值
#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include <mutex>
#include <vector>
using namespace std;
std::mutex g_mutex;
std::shared_ptr<int> g_instance = std::make_shared<int>(0);
constexpr int maxLoop = 10000;
void ThreadFunc()
{
for (int i = 0; i < maxLoop; i++) {
std::shared_ptr<int> tmp = g_instance;
(*tmp)++;
}
cout << "g_instance use count : " << g_instance.use_count() << endl;
}
int main()
{
*g_instance = 0;
vector<std::thread> vc;
for (int i = 0; i < 10; i++) {
vc.push_back(std::thread(ThreadFunc));
}
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
for (auto &t : vc) {
t.join();
}
cout << __FUNCTION__ << "-> g_instance : " << *g_instance << endl;
return 0;
}
- 输出,发现g_instance并没有预想的加到10000
1.2.加锁解决
在上面的程序加一行代码std::lock_guard<std::mutex> lock(g_mutex);
#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include <mutex>
#include <vector>
using namespace std;
std::mutex g_mutex;
std::shared_ptr<int> g_instance = std::make_shared<int>(0);
constexpr int maxLoop = 10000;
void ThreadFunc()
{
for (int i = 0; i < maxLoop; i++) {
std::shared_ptr<int> tmp = g_instance;
////////////////////////////////// 加锁
std::lock_guard<std::mutex> lock(g_mutex);
(*tmp)++;
}
cout << "g_instance use count : " << g_instance.use_count() << endl;
}
int main()
{
*g_instance = 0;
vector<std::thread> vc;
for (int i = 0; i < 10; i++) {
vc.push_back(std::thread(ThreadFunc));
}
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
for (auto &t : vc) {
t.join();
}
cout << __FUNCTION__ << "-> g_instance : " << *g_instance << endl;
return 0;
}
- 输出
2.tips: constexpr的作用
constexpr是一种在编译时求值的机制,它不仅限于变量的声明,还可以用于函数、表达式等,旨在提高代码的性能、安全性和易读性
具体用法见上文和下面的参考
3.结论
- shared_ptr本身的引用计数是原子操作,线程安全
- 但是在多线程环境下,多个对象指向同一个shared_ptr,进行读写操作,并非线程安全
4.参考
标签:
c/c++ & python
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2021-05-26 c/c++ 内存泄漏分析