互斥锁是否正常工作?不能死锁

Is mutex locks note working properly? Can't Deadlock

所以我正在尝试制作一个应该死锁的 C++ 程序。使用我的以下代码,我相信它应该可以工作但不会死锁。是我的 mutex.lock() 没有正常工作吗?我的意思是,如果 mut2.lock() 锁定关键部分,它应该解锁直到它正确完成意味着 funcA 不应该 运行 或者至少等到 mut2.unlock() 因为他们都使用资源rs2?为什么我不能让程序死锁?

#include <iostream>
#include <thread>
#include <mutex>
#include <pthread.h>
#include <cstdio>   // getchar
#include <thread>   // this_thread, yield
#include <future>   // async
#include <chrono>   // seconds
#include <unistd.h>
using namespace std;
mutex mut1, mut2, mut3;
int rs1=1; int rs2 = 2; int rs3=3;
int MAX = 20;

void funcA(){

    mut1.lock();
    cout<<"mut1 lock for thread A\n";
    for(int i=0; i<MAX; i++){
        rs2 = i;
    cout<<"[Aloop]rs1: "<<rs1<<" rs2: "<<rs2<<" rs3: "<<rs3<<" i:"<<i << endl;
    }
    rs1 = rs2;
    cout<<"[A]rs1: "<<rs1<<" rs2: "<<rs2<<" rs3: "<<rs3 << endl;
    mut1.unlock();
    cout<<"mut1 unlock for thread A\n";
}
void funcB(){

    mut2.lock();
    cout<<"mut2 lock for thread B\n";
    rs3 = rs1 + rs2;
    cout<<"[B]rs3: "<<rs3 << " rs1: "<<rs1 << " rs2: "<<rs2 <<endl;
    sleep(50);
    mut2.unlock();  
    cout<<"mut2 unlock for thread B\n";
}


int main(){
    thread tA(funcA);
    thread tB(funcB);

    tA.join();
    tB.join();

return 0;
}

//Here is my makefile
#Makefile project 2

project2: project2.o
    g++ -std=c++11 -pthread -o project2 project2.o
project2.o: project2.cpp project2.h
    g++ -std=c++11 -Wall -pthread -c project2.cpp
    //Below is my output

mut2 lock for thread B

[B]rs3: 3 rs1: 1 rs2: 99

mut1 lock for thread A

[Aloop]rs1: 1 rs2: 0 rs3: 3 i:0

[Aloop]rs1: 1 rs2: 1 rs3: 3 i:1

[Aloop]rs1: 1 rs2: 2 rs3: 3 i:2

[Aloop]rs1: 1 rs2: 3 rs3: 3 i:3

[Aloop]rs1: 1 rs2: 5 rs3: 3 i:5

[Aloop]rs1: 1 rs2: 6 rs3: 3 i:6

[Aloop]rs1: 1 rs2: 7 rs3: 3 i:7

[Aloop]rs1: 1 rs2: 8 rs3: 3 i:8

[Aloop]rs1: 1 rs2: 9 rs3: 3 i:9

[Aloop]rs1: 1 rs2: 10 rs3: 3 i:10

[Aloop]rs1: 1 rs2: 11 rs3: 3 i:11

[Aloop]rs1: 1 rs2: 12 rs3: 3 i:12

[Aloop]rs1: 1 rs2: 13 rs3: 3 i:13

[Aloop]rs1: 1 rs2: 14 rs3: 3 i:14

[Aloop]rs1: 1 rs2: 15 rs3: 3 i:15

[Aloop]rs1: 1 rs2: 16 rs3: 3 i:16

[Aloop]rs1: 1 rs2: 17 rs3: 3 i:17

[Aloop]rs1: 1 rs2: 18 rs3: 3 i:18

[Aloop]rs1: 1 rs2: 19 rs3: 3 i:19

[A]rs1: 19 rs2: 19 rs3: 3

mut1 unlock for thread A

mut2 unlock for thread B

这两个线程试图锁定不同的互斥量,因此它们不可能死锁。

虽然人们可以通过多种不同的方式想象线程死锁,但除非一个线程试图获取另一个线程持有的互斥量,否则不会发生互斥量的死锁。 (当然,其他事情也需要发生。如果发生这种情况,它只会等待另一个线程释放互斥锁而不是死锁。)

您的问题是资源 rs2 不是 "protected",因为它不受单个互斥锁的保护。只要在范围内,任何人都可以随时访问变量。这就是为什么要使用互斥锁来避免两个线程互相踩到脚趾的原因。

试试这个;使用单个互斥量并将其命名为 rs2Mutex。任何时候一个线程想要使用 rs2 它必须锁定 rs2Mutex 并且只锁定 rs2Mutex。这会给你想要的结果。

作为一般的经验法则,我总是根据它们要保护的内容来命名我的互斥量。这有助于避免混淆,并使您和以后关注您的人更容易进行故障排除。看到您进行试验并试图找出问题所在,真是令人振奋。继续努力,确保您了解基本原理,以后线程对您来说会简单得多。