为什么临时的std::lock_guard对象会立即解锁?

问题描述 投票:0回答:1

我正在学习

std::mutex
std::thread
,我对下面两段代码的不同行为感到惊讶:

#include <iostream>
#include <mutex>
#include <thread>

std::mutex mtx;

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

看起来

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

c++ c++11 stdthread temporary-objects stdmutex
1个回答
17
投票

本声明

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

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

本次 CppCon 演讲(从 31:42 开始)中,演示者列出了创建未绑定到局部变量的临时

std::lock_guard
实例作为 Facebook 代码库中的常见错误。

© www.soinside.com 2019 - 2024. All rights reserved.