~scoped_lock()
{ std::apply([](auto&... __m) { (__m.unlock(), ...); }, _M_devices); }
どうやって理解する[](auto&... __m) { (__m.unlock(), ...);
?インラムダを理解していませ...
ん。また、これがミューテックスを逆の順序で解放する方法もわかりません。
@HolyBlackCat が言うように、
(__m.unlock(), ...)
を意味(__m1.unlock(),(__m2.unlock(), (__m3.unlock(), (...))))
しますが、逆の順序でのロック解除は実装しません。
cppreference.com で:
scoped_lock オブジェクトが作成されたスコープから制御が離れると、scoped_lock は破棄され、ミューテックスは逆の順序で解放されます。
これを確認するために、次のような実験を行います。
#include <chrono>
#include <iostream>
#include <mutex>
#include <thread>
class mymutex : public std::mutex {
public:
void lock() {
std::mutex::lock();
std::cout << "mutex " << _i << " locked" << std::endl;
}
mymutex(int i): _i(i){}
bool try_lock() {
bool res = std::mutex::try_lock();
if (res) {
std::cout << "mutex " << _i << " try locked" << std::endl;
}
return res;
}
void unlock() {
std::mutex::unlock();
std::cout << "mutex " << _i << " unlocked" << std::endl;
}
private:
int _i;
};
class Speaking {
private:
int a;
mymutex my1;
mymutex my2;
mymutex my3;
public:
Speaking() : a(0), my1(1), my2(2), my3(3){};
~Speaking() = default;
void speak_without_lock();
void speak_with_three_lock();
};
void Speaking::speak_without_lock() {
std::cout << std::this_thread::get_id() << ": " << a << std::endl;
a++;
}
void Speaking::speak_with_three_lock()
{
std::scoped_lock<mymutex, mymutex, mymutex> scoped(my1, my2, my3);
speak_without_lock();
}
int main() {
Speaking s;
s.speak_with_three_lock();
return 0;
}
mutex 1 locked
mutex 2 try locked
mutex 3 try locked
1: 0
mutex 1 unlocked
mutex 2 unlocked
mutex 3 unlocked
では、cppreference は間違いを犯しますか?