- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
This question让我质疑我多年来一直遵循的做法。
对于函数局部静态常量对象的线程安全初始化,我保护对象的实际构造,但不保护函数局部的初始化引用 指它。像这样的:
namespace {
const some_type& create_const_thingy()
{
lock my_lock(some_mutex);
static const some_type the_const_thingy;
return the_const_thingy;
}
}
void use_const_thingy()
{
static const some_type& the_const_thingy = create_const_thingy();
// use the_const_thingy
}
这个想法是锁定需要时间,如果引用被多个线程覆盖,那就没关系了。
如果是这个我会很感兴趣
我想知道这个的原因是我想知道我是否可以让代码保持原样,或者我是否需要回去修复这个问题。
对于好奇的人:
我使用的许多这样的函数局部静态 const 对象都是映射,它们在第一次使用时从 const 数组初始化并用于查找。例如,我有一些 XML 解析器,其中标记名称字符串映射到 enum
值,因此我可以稍后在标记的 enum
上 switch
值(value)观。
由于我得到了一些关于该做什么的答案,但还没有得到我实际问题的答案(请参阅上面的 1. 和 2.),我将对此展开悬赏。再次:
我对自己能做什么不感兴趣,我真的很想知道这个。
最佳答案
这是我第二次尝试回答。我只会回答你的第一个问题:
- safe enough in practice?
没有。正如您所说的,您只是确保对象创建受到保护,而不是对对象的引用的初始化。
在没有 C++98 内存模型且编译器供应商没有明确声明的情况下,无法保证写入表示实际引用的内存和写入保存初始化标志值的内存 (如果这就是它的实现方式),则从多个线程中以相同的顺序查看引用。
正如您还说的,用相同的值多次覆盖引用应该没有语义差异(即使存在单词撕裂,这在您的处理器架构上通常不太可能,甚至可能是不可能的)但是有一种情况是它重要:当多个线程在程序执行期间第一次竞相调用函数时。在这种情况下,这些线程中的一个或多个可能会在实际引用被初始化之前看到初始化标志被设置。
您的程序中有一个潜在的错误,您需要修复它。至于优化,我相信除了使用双重检查锁定模式之外还有很多。
关于c++ - 函数局部静态 const 对象的线程安全初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2955921/
我是一名优秀的程序员,十分优秀!