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

问题描述 投票:0回答:1

我正在教自己一些有关并发编程的知识,特别是在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将完成,然后允许task_two开始)。但是,我用相同的结果运行了好几次。另外,如果我关于锁和线程的说法不正确,请更正我。

c++ multithreading locking mutex deadlock
1个回答
0
投票

仅由于死锁can发生(确实如此,在发布的代码中确实如此),并不意味着它总是will发生。

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

多线程就是这样:滑。

© www.soinside.com 2019 - 2024. All rights reserved.