面试题答案
一键面试可能遇到的问题
- 数据竞争:多个线程同时读写
std::shared_ptr
时,可能导致数据不一致。比如一个线程正在释放对象(shared_ptr
计数减为0),而另一个线程还在尝试访问该对象,这会导致悬空指针访问,引发未定义行为。
解决方法
- 使用互斥锁(
std::mutex
):通过互斥锁来保护对std::shared_ptr
的访问,确保同一时间只有一个线程可以对其进行读写操作。
以下是使用互斥锁解决问题的代码示例:
#include <iostream>
#include <memory>
#include <mutex>
#include <thread>
std::mutex sharedPtrMutex;
std::shared_ptr<int> sharedData;
void readSharedData() {
std::unique_lock<std::mutex> lock(sharedPtrMutex);
if (sharedData) {
std::cout << "Read data: " << *sharedData << std::endl;
}
}
void writeSharedData() {
std::unique_lock<std::mutex> lock(sharedPtrMutex);
sharedData = std::make_shared<int>(42);
std::cout << "Write data: " << *sharedData << std::endl;
}
int main() {
std::thread readThread(readSharedData);
std::thread writeThread(writeSharedData);
readThread.join();
writeThread.join();
return 0;
}
- 使用原子操作的智能指针(
std::atomic_shared_ptr
):C++20引入了std::atomic_shared_ptr
,它提供了原子性的操作,能避免数据竞争问题。
以下是使用 std::atomic_shared_ptr
的代码示例:
#include <iostream>
#include <memory>
#include <atomic>
#include <thread>
std::atomic_shared_ptr<int> sharedData;
void readSharedData() {
auto data = sharedData.load();
if (data) {
std::cout << "Read data: " << *data << std::endl;
}
}
void writeSharedData() {
sharedData.store(std::make_shared<int>(42));
std::cout << "Write data: " << *sharedData.load() << std::endl;
}
int main() {
std::thread readThread(readSharedData);
std::thread writeThread(writeSharedData);
readThread.join();
writeThread.join();
return 0;
}
在实际应用中,如果使用的是C++20及以上版本,优先考虑 std::atomic_shared_ptr
,因为它不需要额外的锁机制,性能更高;如果是C++20以下版本,使用 std::mutex
来保护 std::shared_ptr
的访问。