简体   繁体   English

通过引用“ std :: lock_guard”返回共享对象是否安全? <mutex> “?

[英]Is it safe to return a shared object by reference with “std::lock_guard<mutex>”?

#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();
}

If Cleaner is executed after return g_coll; 如果在return g_coll;之后执行了Cleaner return g_coll; , does the C++ standard guarantee that returned_coll contains { "hello" } ? ,C ++标准是否保证 returned_coll包含{ "hello" }

No, this is not safe. 不,这不安全。

Semantically, the order of events when a function of non-void return type returns is as follows: 语义上,非无效返回类型的函数返回时的事件顺序如下:

  1. The expression in the return statement is evaluated. 将对return语句中的表达式进行求值。
  2. The return value is copy-initialized from said expression. 返回值从所述表达式被复制初始化。
  3. Automatic local variables are destroyed in the reverse order of construction. 自动局部变量按照相反的顺序销毁。
  4. Control is returned to the caller. 控制权返回给调用者。

Note that returned_coll is not the return value. 请注意, returned_coll不是返回值。 Rather, Getter() is the return value. 相反, Getter()是返回值。 The initialization of returned_coll from the lvalue returned by Getter() occurs after step 4. Getter() returned_coll的左值初始化Getter()步骤是在步骤4之后。

Therefore, when returned_coll is copy-initialized from Getter() , the mutex held by Getter will have already been released, which means the initialization of returned_coll may race with the access in Cleaner . 因此,当returned_coll从复制初始化Getter()召开互斥Getter将已经被释放,这意味着初始化returned_coll可在访问比赛Cleaner

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM