基于范围的锁定保护和返回值的时间安排

时间:2016-01-11 21:20:06

标签: c++ scope rvo

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.
     }
};

关于警卫和复制返回值的保证时间是多少? 是否会在锁定时发生复制,或者在允许(或实际!)优化的情况下,可以在函数体返回后完成其中一些复制?

2 个答案:

答案 0 :(得分:4)

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

优化不会改变这一事实,它们只会更改副本的目标 - 它可以是中间临时或呼叫站点上的真实目的地。锁定只存在于第一个副本中,无论它发送到何处。

但是,请记住代码中的实际范围锁定不正确。您需要lock_guard - 但它可能只是一个演示复制粘贴错误,真正的代码具有真正的防范。

答案 1 :(得分:4)

std::lock 确定范围守卫!它只会锁定。它没有解锁。你想要这个:

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

锁定构造并在销毁时解锁(在范围退出时发生)。

返回值的初始化将在局部变量被销毁之前发生,因此在保持锁定时。不允许编译器优化中断正确的同步代码。

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