6

我正在学习std::mutexstd::thread我对以下 2 段代码的不同行为感到惊讶:

#include <iostream>
#include <mutex>
#include <thread>
using namespace std;

std::mutex mtx;

void foo(int k)
{
    std::lock_guard<std::mutex> lg{ mtx };
    for (int i = 0; i < 10; ++i)
        cout << "This is a test!" << i << endl;
    cout << "The test " << k << " has been finished." << endl;
}

int main()
{
    std::thread t1(foo, 1);
    std::thread t2(foo, 2);
    t1.join();
    t2.join();
    return 0;
}

输出是顺序的。但是如果我不命名变量std::lock_guard<std::mutex>,则输出是无序的

void foo(int k)
{
    std::lock_guard<std::mutex> { mtx }; // just erase the name of variable
    for (int i = 0; i < 10; ++i)
        cout << "This is a test!" << i << endl;
    cout << "The test " << k << " has been finished." << endl;
}

在第二种情况下似乎std::lock_guard没有用,为什么?

4

1 回答 1

17

本声明

std::lock_guard<std::mutex> { mtx };

不会将创建的对象绑定到名称,它是仅针对此特定语句存在的临时变量。与此相反,具有名称并在堆栈上创建的变量将一直存在,直到创建它的范围结束。

此 CppCon 演讲中(从31:42开始),演讲者将创建std::lock_guard未绑定到局部变量的临时实例列为 Facebook 代码库中的常见错误。

于 2018-08-22T08:55:37.273 回答