学习互斥锁和线程 - 关于竞争条件的问题
Posted
技术标签:
【中文标题】学习互斥锁和线程 - 关于竞争条件的问题【英文标题】:Learning about mutexes and threads - Question regarding race conditions 【发布时间】:2020-05-05 23:25:26 【问题描述】:我正在自学一些关于并发编程的知识,特别是在 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
开始)。但是,我运行了很多次,结果相同。另外,如果我关于锁和线程的措辞不正确,请纠正我。
【问题讨论】:
【参考方案1】:仅仅因为死锁可以发生(正如在发布的代码中确实可以),并不意味着它总是会发生。
在您的情况下,task_one
恰好在 task_two
开始之前运行完成。
多线程就是这样:很滑。
【讨论】:
那么如果我对竞态条件的定义(执行顺序影响最终输出)是正确的,那么这段代码就表现出竞态条件?以上是关于学习互斥锁和线程 - 关于竞争条件的问题的主要内容,如果未能解决你的问题,请参考以下文章