shared_ptr的引用计数线程安全,但所指对象的访问需额外同步。

shared_ptr
std::mutex
在我看来,理解
shared_ptr
shared_ptr
shared_ptr
shared_ptr
然而,这种安全性仅限于
shared_ptr
shared_ptr
*ptr
ptr->member
shared_ptr
shared_ptr
shared_ptr
shared_ptr
要真正安全地在多线程中使用
shared_ptr
std::mutex
std::shared_mutex
立即学习“C++免费学习笔记(深入)”;
shared_ptr
这个问题其实触及了C++标准库设计哲学的一个核心点:提供工具,而不是强制行为。
shared_ptr
std::atomic
shared_ptr
shared_ptr
然而,
shared_ptr
shared_ptr
int
shared_ptr
shared_ptr
shared_ptr
正确保护
shared_ptr
使用互斥锁(std::mutex
shared_ptr
std::mutex
#include <iostream>
#include <memory>
#include <thread>
#include <mutex>
#include <vector>
class MyData {
public:
int value;
MyData(int v = 0) : value(v) {}
void increment() { value++; }
};
std::shared_ptr<MyData> global_data = std::make_shared<MyData>(0);
std::mutex data_mutex;
void worker_function() {
for (int i = 0; i < 10000; ++i) {
std::lock_guard<std::mutex> lock(data_mutex); // 保护数据访问
global_data->increment();
}
}
// int main() {
// std::vector<std::thread> threads;
// for (int i = 0; i < 4; ++i) {
// threads.emplace_back(worker_function);
// }
// for (auto& t : threads) {
// t.join();
// }
// std::cout << "Final value: " << global_data->value << std::endl; // 应该接近 40000
// return 0;
// }这种方式确保了在任何时刻,只有一个线程能够修改
global_data->value
std::lock_guard
采用不可变数据(Immutable Data)策略: 如果你的数据对象在创建后就不会再被修改,那么它就是天然线程安全的。多个线程可以自由地读取它,而无需任何锁。这是一种非常强大的并发模式,因为它完全消除了数据竞争的可能性,并且通常能带来更好的性能。当需要“修改”数据时,实际上是创建一个新的、修改后的数据副本,然后更新
shared_ptr
#include <iostream>
#include <memory>
#include <thread>
#include <mutex>
#include <vector>
class ImmutableData {
public:
const int value;
ImmutableData(int v) : value(v) {}
// 没有修改成员的方法
};
std::shared_ptr<const ImmutableData> current_data = std::make_shared<const ImmutableData>(0);
std::mutex update_mutex; // 保护指针本身的更新
void updater_function() {
for (int i = 0; i < 1000; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // 模拟一些工作
std::lock_guard<std::mutex> lock(update_mutex);
current_data = std::make_shared<const ImmutableData>(current_data->value + 1); // 创建新对象并更新指针
}
}
void reader_function() {
for (int i = 0; i < 1000; ++i) {
std::shared_ptr<const ImmutableData> local_copy;
{
std::lock_guard<std::mutex> lock(update_mutex); // 保护指针读取
local_copy = current_data; // 获取当前指针的副本
}
// 现在可以安全地读取local_copy指向的数据,因为它是不可变的
// std::cout << "Read value: " << local_copy->value << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
// int main() {
// std::vector<std::thread> threads;
// threads.emplace_back(updater_function);
// for (int i = 0; i < 3; ++i) {
// threads.emplace_back(reader_function);
// }
// for (auto& t : threads) {
// t.join();
// }
// std::cout << "Final value: " << current_data->value << std::endl;
// return 0;
// }需要注意的是,虽然数据本身是不可变的,但
shared_ptr
使用std::atomic<std::shared_ptr<T>>
std::atomic<std::shared_ptr<T>>
shared_ptr
shared_ptr
#include <iostream>
#include <memory>
#include <thread>
#include <atomic>
#include <vector>
class MyHeavyData {
public:
int id;
MyHeavyData(int i) : id(i) {
// std::cout << "MyHeavyData " << id << " created." << std::endl;
}
~MyHeavyData() {
// std::cout << "MyHeavyData " << id << " destroyed." << std::endl;
}
};
std::atomic<std::shared_ptr<MyHeavyData>> atomic_data;
void writer_atomic() {
for (int i = 0; i < 5; ++i) {
std::shared_ptr<MyHeavyData> new_ptr = std::make_shared<MyHeavyData>(i);
atomic_data.store(new_ptr); // 原子地更新指针
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
void reader_atomic() {
for (int i = 0; i < 10; ++i) {
std::shared_ptr<MyHeavyData> current_ptr = atomic_data.load(); // 原子地读取指针
if (current_ptr) {
// std::cout << "Reader got data ID: " << current_ptr->id << std::endl;
}
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
}
// int main() {
// atomic_data.store(std::make_shared<MyHeavyData>(-1)); // 初始值
// std::vector<std::thread> threads;
// threads.emplace_back(writer_atomic);
// threads.emplace_back(reader_atomic);
// threads.emplace_back(reader_atomic);
// for (auto& t : threads) {
// t.join();
// }
// return 0;
// }需要强调的是,
std::atomic<std::shared_ptr<T>>
T
current_ptr
current_ptr->id
shared_ptr
shared_ptr
在多线程中使用
shared_ptr
传递方式的选择:按值、按const
weak_ptr
std::shared_ptr<T> p
const
const std::shared_ptr<T>& p
shared_ptr
const
shared_ptr
std::weak_ptr
weak_ptr
shared_ptr
weak_ptr
lock()
shared_ptr
lock()
shared_ptr
shared_ptr
lock()
#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
class MyObject {
public:
int id;
MyObject(int i) : id(i) { std::cout << "Object " << id << " created." << std::endl; }
~MyObject() { std::cout << "Object " << id << " destroyed." << std::endl; }
};
void observe_object(std::weak_ptr<MyObject> weak_obj) {
std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 模拟一些延迟
if (std::shared_ptr<MyObject> locked_obj = weak_obj.lock()) {
std::cout << "Observer: Object " << locked_obj->id << " is still alive." << std::endl;
} else {
std::cout << "Observer: Object has been destroyed." << std::endl;
}
}
// int main() {
// std::shared_ptr<MyObject> shared_obj = std::make_shared<MyObject>(10);
// std::thread t(observe_object, std::weak_ptr<MyObject>(shared_obj));
// shared_obj.reset(); // 主线程释放shared_ptr,对象可能会被销毁
// t.join();
// return 0;
// }避免循环引用导致的内存泄漏: 这是
shared_ptr
shared_ptr
shared_ptr
weak_ptr
weak_ptr
从this
shared_ptr
enable_shared_from_this
以上就是C++如何在多线程中安全使用shared_ptr的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号