下面是演示代码片段。
由于 std::shared_ptr
本身是线程安全的并且托管对象永远不会被生产者和消费者同时访问,因此可以删除 mutex
吗?
#include <memory>
#include <mutex>
#include <thread>
struct Demo {
int i;
float f;
};
using SCDemoPtr = std::shared_ptr<Demo>;
class ResultManager {
public:
ResultManager();
void SetFrontRes(SCDemoPtr oms_result);
void SetBackRes(SCDemoPtr oms_result);
void MergeResults();
private:
std::mutex front_mutex;
std::mutex back_mutex;
SCDemoPtr front_result;
SCDemoPtr back_result;
};
ResultManager::ResultManager() {}
void ResultManager::SetFrontRes(SCDemoPtr oms_res) {
std::lock_guard<std::mutex> guard(front_mutex);
front_result = oms_res;
}
void ResultManager::SetBackRes(SCDemoPtr oms_res) {
std::lock_guard<std::mutex> guard(back_mutex);
back_result = oms_res;
}
void ResultManager::MergeResults() {
SCDemoPtr cur_front_res;
SCDemoPtr cur_back_res;
{
std::lock_guard<std::mutex> guard(front_mutex);
cur_front_res = front_result;
}
{
std::lock_guard<std::mutex> guard(back_mutex);
cur_back_res = back_result;
}
if (cur_front_res == nullptr || cur_back_res == nullptr) {
return;
}
SCDemoPtr merge_res(new Demo);
merge_res->i = cur_front_res->i + cur_back_res->i;
}
int main() {
ResultManager res_manager;
std::thread producer1([&res_manager]() {
while (true) {
SCDemoPtr res(new Demo);
res->i = 1;
res->f = 3.14;
res_manager.SetFrontRes(res);
std::this_thread::sleep_for(std::chrono::seconds(1));
}
});
std::thread producer2([&res_manager]() {
while (true) {
SCDemoPtr res(new Demo);
res->i = 1;
res->f = 3.14;
res_manager.SetBackRes(res);
std::this_thread::sleep_for(std::chrono::seconds(1));
}
});
while (true) {
res_manager.MergeResults();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
producer1.join();
producer2.join();
return 0;
}
最佳答案
Could the mutex be removed since std::shared_ptr itself is thread-safe
不,对 std::shared_ptr
本身的访问不是线程安全的,并且与访问任何其他对象的行为没有任何不同。当另一个线程尝试访问它时尝试修改它会导致数据竞争并导致未定义的行为。
对于 std::shared_ptr
来说,唯一的事情是托管对象的生命周期,它保证被一个线程销毁。
关于c++ - 当永远不会同时访问共享托管对象时,在生产者和消费者之间使用 std::shared_ptr 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77253184/