1. 不同线程对std::shared_ptr
对象的独立操作
- 操作:不同线程对各自独立的
std::shared_ptr
对象进行创建、销毁、赋值等操作时是线程安全的。
- 举例:
#include <memory>
#include <thread>
void threadFunction1() {
std::shared_ptr<int> ptr1 = std::make_shared<int>(10);
// 对ptr1进行其他操作,如解引用等
}
void threadFunction2() {
std::shared_ptr<int> ptr2 = std::make_shared<int>(20);
// 对ptr2进行其他操作,如解引用等
}
int main() {
std::thread t1(threadFunction1);
std::thread t2(threadFunction2);
t1.join();
t2.join();
return 0;
}
- 原因:每个
std::shared_ptr
对象有自己独立的引用计数,不同线程操作不同的std::shared_ptr
对象不会相互干扰,因此是线程安全的。
2. 多个线程对同一个std::shared_ptr
对象的读操作
- 操作:多个线程同时对同一个
std::shared_ptr
对象进行读操作(例如获取指向对象的指针或访问引用计数)是线程安全的。
- 举例:
#include <memory>
#include <iostream>
#include <thread>
std::shared_ptr<int> globalPtr;
void readSharedPtr() {
std::cout << "Thread reads value: " << *(globalPtr.get()) << std::endl;
std::cout << "Thread reads ref count: " << globalPtr.use_count() << std::endl;
}
int main() {
globalPtr = std::make_shared<int>(42);
std::thread t1(readSharedPtr);
std::thread t2(readSharedPtr);
t1.join();
t2.join();
return 0;
}
- 原因:
std::shared_ptr
的引用计数和指向对象的指针的读取操作通常是原子操作,多个线程同时读取不会导致数据竞争。
3. 多个线程对同一个std::shared_ptr
对象的写操作
- 操作:多个线程对同一个
std::shared_ptr
对象进行写操作(如赋值、reset等改变引用计数或指向对象的操作)不是线程安全的,需要额外的同步机制。
- 举例:
#include <memory>
#include <iostream>
#include <thread>
std::shared_ptr<int> globalPtr;
void writeSharedPtr() {
globalPtr = std::make_shared<int>(10);
}
int main() {
std::thread t1(writeSharedPtr);
std::thread t2(writeSharedPtr);
t1.join();
t2.join();
// 这里可能会出现未定义行为,因为没有同步机制
std::cout << "Final ref count: " << globalPtr.use_count() << std::endl;
return 0;
}
- 原因:写操作会改变引用计数和指向对象的指针,多个线程同时进行写操作可能导致引用计数混乱或指针指向错误,从而引发未定义行为。若要保证线程安全,可使用
std::mutex
等同步机制:
#include <memory>
#include <iostream>
#include <thread>
#include <mutex>
std::shared_ptr<int> globalPtr;
std::mutex ptrMutex;
void writeSharedPtr() {
std::lock_guard<std::mutex> lock(ptrMutex);
globalPtr = std::make_shared<int>(10);
}
int main() {
std::thread t1(writeSharedPtr);
std::thread t2(writeSharedPtr);
t1.join();
t2.join();
std::cout << "Final ref count: " << globalPtr.use_count() << std::endl;
return 0;
}