通过&#34; std :: lock_guard <mutex>&#34;引用返回共享对象是否安全?

时间:2017-02-13 03:08:11

标签: c++ multithreading c++11 locking standards

#include <vector>
#include <string>
#include <mutex>
#include <future>

using namespace std;

mutex g_mtx;
vector<string> g_coll;

void Cleaner()
{
    lock_guard<mutex> lock(g_mtx);
    g_coll.clear();
}

const vector<string>& Getter()
{
    lock_guard<mutex> lock(g_mtx);
    return g_coll;
}

int main()
{
    g_coll = { "hello" };
    auto fut = async([&]()
    {
        Cleaner();
    });

    auto returned_coll = Getter();
    fut.get();
}

如果在Cleaner之后执行return g_coll;,那么returned_coll包含{ "hello" }的C ++标准保证是什么?

1 个答案:

答案 0 :(得分:5)

不,这不安全。

从语义上讲,非void返回类型函数返回时的事件顺序如下:

  1. 评估return语句中的表达式。
  2. 返回值是从所述表达式复制初始化的。
  3. 自动局部变量以相反的构造顺序销毁。
  4. 控制权返回给来电者。
  5. 请注意,returned_coll不是返回值。相反,Getter()是返回值。从returned_coll返回的左值初始化Getter()发生在步骤4之后。

    因此,当returned_collGetter()复制初始化时,Getter所持有的互斥锁已经被释放,这意味着returned_coll的初始化可能会与Cleaner中的访问权限。