gpt4 book ai didi

multithreading - C++ 11 const-我的代码是线程安全的吗?

转载 作者:行者123 更新时间:2023-12-03 12:54:31 27 4
gpt4 key购买 nike

我有以下类(class):

class Object 
{
public:
Object() {}

const std::string& get_name() const
{
if(_name.empty()) {
std::lock_guard<std::mutex> lock(_lock);

// Check if its still empty. Some other thread might have gotten here first
if(_name.empty()) {
//Run expensive operation
_name = get_object_name();
}
}

return _name;
}

private:
std::string get_object_name(); // <- Expensive function

mutable std::mutex _lock;
mutable std::string _name;
};

由于 get_object_name是一个昂贵的函数,因此我想进行某种延迟的初始化,并且仅在首次调用 get_name()时才调用它。如果从未调用过它,那么我不会浪费资源来获取这个名称。

我担心第一次调用 _name.empty()。我当前的代码是否保证是线程安全的,还是需要将锁移到函数顶部?

我观看了Herb Sutter的一些演讲,特别是 this one,该幻灯片在其中出现:

http://i.imgur.com/Jz4luYe.png

这使我相信对 empty()的调用是线程安全的。但是我的变量( _name)是 mutable。该“const ==线程安全”规则在这里仍然适用吗?

对此, get_name()是唯一可以修改 _name的函数。

最佳答案

不,这不是线程安全的,因为您(读取)在_name之外访问mutex,这会破坏同步。

一种可能的解决方案是使用标准库提供的std::call_once机制。

class Object
{
public:
Object() {}

const std::string& get_name() const
{
std::call_once(flag, [&] { _name = get_object_name(); });

return _name;
}

private:
std::string get_object_name() const; // <- Expensive function

mutable std::string _name;
mutable std::once_flag flag;
};

这样可以保证 get_object_name()不会被多次调用。第一次调用将初始化 string,并发调用将阻塞,直到lambda完成。
同步已得到充分处理,这意味着任何引用了 string的线程都可以安全地从中读取信息。

关于multithreading - C++ 11 const-我的代码是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44527103/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com