了解互斥和线程-有关竞争条件的问题

时间:2020-05-05 23:25:26

标签: c++ multithreading locking mutex deadlock

我正在自学一些关于并发编程的知识,特别是在C ++中使用互斥锁和线程。我写了下面的小例子:

#include <iostream>
#include <thread>
#include <mutex>
// #include <chrono>

std::mutex M1,M2;

void task_one () {
    std::cout << "AAAA!\n";
    M1.lock();
    // std::cout << "M1 locked in A\n";
    M2.lock();
    // std::cout << "M2 locked in A\n";
    std::cout << "BBBB!\n";
    M2.unlock();
    // std::cout << "M2 unlocked in A\n";
    M1.unlock();
    // std::cout << "M2 unlocked in A\n";
}

void task_two () {
    std::cout << "CCCC!\n";
    M2.lock();
    // std::cout << "M2 locked in B\n";
    M1.lock();
    // std::cout << "M1 locked in B\n";
    std::cout << "DDDD!\n";
    // M1.unlock();
    // std::cout << "M1 unlocked in B\n";
    M2.unlock();
    // std::cout << "M2 unlocked in B\n";
}

int main () {
    std::thread th1 (task_one);
    std::thread th2 (task_two);
    th1.join();
    th2.join();

    // th1.detach();
    // th2.detach();
    // std::chrono::milliseconds timespan(10);
    // std::this_thread::sleep_for(timespan);
    return 0;
}

我希望此代码可以打印

AAAA!
CCCC!

,然后在task_one尝试获取M2上的锁时死锁(因为task_two已经获取了该锁)。 但是,它会打印

AAAA!
BBBB!
CCCC!
DDDD!

为什么没有僵局?另外,这是竞争条件的示例,还是此代码是线程安全的?我认为这是有竞争条件的,因为如果task_one可以在task_two之前获得M2的锁定,那么一切都会执行(即task_one将完成,然后允许{{1 }} 开始)。但是,我用相同的结果运行了好几次。另外,如果我关于锁和线程的说法不正确,请纠正我。

1 个答案:

答案 0 :(得分:2)

仅仅因为可能发生死锁(确实在发布的代码中可以发生),并不意味着总是会发生

就您而言,task_one恰好在task_two完全运行之前就完成了。

多线程就像这样:滑。

相关问题