【发布时间】:2018-07-08 19:19:01
【问题描述】:
我想这是一个关于左值实例化排序的更一般的问题。
简而言之,这样安全吗?:
void func1()
{
std::lock_guard< std::mutex > lock( mutex );
//do some stuff in locked context
}
void func2()
{
func1();
std::lock_guard< std::mutex > lock( mutex );
//do some stuff in locked context
}
我有点担心编译器可能会在从 func2 中调用 func1 之前调用 lock_guard 的构造函数,从而导致死锁。
是否保证这是安全的还是我需要做这样的事情:
void func1()
{
std::lock_guard< std::mutex > lock( mutex );
//do some stuff in locked context
}
void func2()
{
func1();
{ //lock
std::lock_guard< std::mutex > lock( mutex );
//do some stuff in locked context
} //unlock
}
【问题讨论】:
-
您担心的依据是什么?
-
仅凭经验,而不是标准中的空话,我认为它是完全安全的。
-
在没有循环的情况下,执行是纯自上而下的。这包括对象构造。在这两个 sn-ps 中,
func1总是会在对象lock被构造之前被调用。换句话说,它是安全的。在这两种情况下。 -
我不是编译器/优化器如何运行的专家,所以我不确定编译器是否会首先实例化函数中的所有对象,然后开始执行函数,或者它是否会在我编写代码的顺序。显然,函数调用是按照我放置它们的顺序发生的,但是在某些情况下,我可以看到编译器/优化器将左值实例化移动到函数的顶部。我不怀疑它确实有很多人可能会遇到麻烦,我只是想确保这不会发生。
-
如果您不是专家,通常根本不应该考虑编译器。只需遵循语言规则,并相信您的工具通常是实用且有效的。
标签: c++ c++11 locking language-lawyer