c++多线程同步问题
一个mutex导致的死锁问题
单核实时可抢占的系统中,优先级不同的三个线程A/B/C, A>B>C
- 当C先获得时间片开始执行,并获得锁
- A因为高优先级,被唤醒并中断C,但没有得到锁,而阻塞
- B获得执行机会,由于优先级高于C,B会一直执行,让AC系统无法取得任何进展
std::stack<T> stack;
std::mutex mutex;
void push(const T& obj) {
   mutex.lock();
   stack.push(obj);
   mutex.unlock();
}

多个mutex导致的死锁问题
- 多个锁共同控制临界区
- 加锁顺序不一致
- A,B锁被两个线程分别持有,等待对方释放剩下的锁,不会主动释放所持有的锁,而导致死锁
#include <mutex>
#include <iostream>
#include <thread>
using namespace std;
mutex lockA;
mutex lockB;
int counter{0};
void foo() {
    while(true) {
        lock_guard<mutex> guardA(lockA);
        lock_guard<mutex> guardB(lockB);
        cout << "message from foo " << counter++ << endl;
    }
}
void bar() {
    while(true) {
        lock_guard<mutex> guardB(lockB); // 注意这里加锁顺序
        lock_guard<mutex> guardA(lockA);
        cout << "message from bar " << counter++ << endl;
    }
}
void DeadLockTest() {
    thread tf(foo);
    thread tb(bar);
    tf.join();
    tb.join();
}
解决多个锁导致死锁问题
- 尽量只用一个锁
- 如果必须用多个锁,注意顺序上锁
- 无法保证上锁顺序的话,使用std::lock
void foo() {
    while(true) {
        std::lock(lockA, lockB);
        lock_guard<mutex> guardA(lockA, std::adopt_lock);
        lock_guard<mutex> guardB(lockB, std::adopt_lock);
        cout << "message from foo " << counter++ << endl;
    }
}
void bar() {
    while(true) {
        std::lock(lockB, lockA);
        lock_guard<mutex> guardB(lockB, std::adopt_lock); // 注意这里加锁顺序
        lock_guard<mutex> guardA(lockA, std::adopt_lock);
        cout << "message from bar " << counter++ << endl;
    }
}
- 或者使用try_lock
void foo() {
    while(true) {
        if (std::try_lock(lockA, lockB) == -1) {
            cout << "message from foo " << counter++ << endl;
            lockA.unlock();
            lockB.unlock();
        }
    }
}
void bar() {
    while(true) {
        if (std::try_lock(lockB, lockA) == -1) {
            cout << "message from bar " << counter++ << endl;
            lockB.unlock();
            lockA.unlock();
        }
    }
}
参考
https://en.cppreference.com/w/cpp/thread/lock
http://en.cppreference.com/w/cpp/thread/lock_guard
https://cplusplus.com/reference/mutex/try_lock/
 
                    
                     
                    
                 
                    
                 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号