Different behavior when `std::lock_guard<std::mutex>` object has no name

  • A+
Category:Languages

I'm learning about std::mutex, std::thread and I am surprised at the different behavior of 2 pieces of code below:

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

The output is sequential. But if I donot name variable std::lock_guard<std::mutex>, the output is unordered

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

It seems like std::lock_guard is no use in 2nd case, Why?

 


This declaration

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

doesn't bind the created object to a name, it's a temporary variable that exists only for this particular statement. Opposed to that, a variable that has a name and is created on the stack lives until the end of the scope in which it's created.

In this CppCon talk (~minute 32), the presenter lists the creation of temporary std::lock_guard instances not bound to a local variable as a common bug in the Facebook code base.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: