基于作用域的锁保护和 return 值的时间

Timing of scope-based lock guards and return values

class C {
    mutable std::mutex _lock;
    map<string,string> deep_member;
public:
    auto get_big_lump()
     {
     std::unique_lock<std::mutex> lock(_lock); // establish scope guard
     return deep_member;  // copy the stuff while it can't be changed on another thread.
     }
};

守卫和复制 return 值的保证时间是多少? 在允许(或实际!)优化的情况下,是否会在持有锁时进行复制,或者其中一些是否可以在函数体 returns 之后完成?

局部对象的所有析构函数在函数体终止后调用。 Return 语句是函数体的一部分,因此保证在执行复制时保持锁定。

优化不会改变这一事实,它们只会改变副本的目的地——它可以是中间临时目的地,也可以是调用站点上的真实目的地。锁只存在于第一个副本,无论它被发送到哪里。

但是,请记住代码中的实际作用域锁是不正确的。您需要 lock_guard - 但它可能只是一个演示 copy-paste 错误,真正的代码有真正的保护措施。

std::lock 建立作用域守卫!它只会锁定。它不解锁。你想要这个:

std::unique_lock<std::mutex> lock(_lock);

在构建时锁定并在销毁时解锁(发生在作用域退出时)。

return 值的初始化将发生在局部变量被销毁之前,因此在持有锁时。不允许编译器优化破坏正确同步的代码。

但是,请注意,如果 return 值随后被复制或移动到其他变量中,则第二次复制或移动将在 锁释放后发生。