两个线程互相等待互斥锁。从而导致死锁。
#include
#include
#include
std::mutex m1;
std::mutex m2;
void f(void)
{
std::lock_guard k(m1);
printf("get lock 1\n");
std::lock_guard k1(m2);
printf("get lock 2\n");
}
void f1(void)
{
std::lock_guard k(m2);
printf("get lock 2\n");
std::lock_guard k1(m1);
printf("get lock 1\n");
}
int main()
{
std::thread t(f);
std::thread t1(f1);
t.join();
t1.join();
printf("main exit\n");
return 0;
}
使用相同的顺序获取锁。不小心即会犯错。
使用 std::lock
同时获取多把锁。std::lock 可以同时锁住多个互斥,但不会自动解锁,需要配合 std::lock_guard 或者 std::unique_lock 使用,使其能够自动解锁。
使用 std::scoped_lock
同时获取多把锁。std::scoped_lock 与 std::lock_guard 完全等价,只不过前者是可变函数模板,可以接收多个互斥。
#include
#include
#include
std::mutex m1;
std::mutex m2;
static int method = 3;
// 需要 c++17
void f(void)
{
// 方法 1,按照相同的顺序获取锁
if (0 == method) {
std::lock_guard k(m1);
printf("thread 1 get lock 1\n");
std::lock_guard k1(m2);
printf("thread 1 get lock 2\n");
}
// 方法 2,std::lock 与 std::lock_guard 配合使用
if (1 == method) {
// 锁住 m1 和 m2
std::lock(m1, m2);
printf("thread 1 get lock 1 and 2\n");
// std::adopt_lock 指明互斥已被锁住
std::lock_guard k(m1, std::adopt_lock);
std::lock_guard k1(m2, std::adopt_lock);
}
// 方法 3,std::lock 与 std::unique_lock 配合使用
if (2 == method) {
// std::defer_lock 指明不需要对互斥进行加锁
std::unique_lock k(m1, std::defer_lock);
std::unique_lock k1(m2, std::defer_lock);
// 锁住 k 和 k1
std::lock(k, k1);
printf("thread 1 get lock 1 and 2\n");
}
// 方法 4,使用 std::scoped_lock
if (3 == method) {
std::scoped_lock k(m1, m2);
printf("thread 1 get lock 1 and 2\n");
}
}
void f1(void)
{
if (0 == method) {
std::lock_guard k(m1);
printf("thread 2 get lock 1\n");
std::lock_guard k1(m2);
printf("thread 2 get lock 2\n");
}
if (1 == method) {
std::lock(m1, m2);
printf("thread 2 get lock 1 and 2\n");
std::lock_guard k(m1, std::adopt_lock);
std::lock_guard k1(m2, std::adopt_lock);
}
if (2 == method) {
std::unique_lock k(m1, std::defer_lock);
std::unique_lock k1(m2, std::defer_lock);
std::lock(k, k1);
printf("thread 2 get lock 1 and 2\n");
}
if (3 == method) {
std::scoped_lock k(m1, m2);
printf("thread 2 get lock 1 and 2\n");
}
}
int main()
{
std::thread t(f);
std::thread t1(f1);
t.join();
t1.join();
printf("main exit\n");
return 0;
}
std::scoped_lock
;