死锁的一点分析

简介: 死锁的一点分析

对多个互斥对象加锁

在某些情况下我们可能需要对多个互斥对象进行加锁,考虑下面的代码

std::mutex mt1, mt2;
// thread 1
{
    std::lock_guard<std::mutex> lck1(mt1);
    std::lock_guard<std::mutex> lck2(mt2);
    // do something
}
// thread 2
{
    std::lock_guard<std::mutex> lck2(mt2);
    std::lock_guard<std::mutex> lck1(mt1);
    // do something
}

如果线程1执行到第5行的时候恰好线程2执行到第11行。那么就会出现

线程1持有mt1并等待mt2

线程2持有mt2并等待mt1

发生死锁

为了避免发生这类死锁,对于任意两个互斥对象,在多个线程中进行加锁时应保证其先后顺序是一致。前面的代码应修改成

std::mutex mt1, mt2;
// thread 1
{
    std::lock_guard<std::mutex> lck1(mt1);
    std::lock_guard<std::mutex> lck2(mt2);
    // do something
}
// thread 2
{
    std::lock_guard<std::mutex> lck1(mt1);
    std::lock_guard<std::mutex> lck2(mt2);
    // do something
}

更好的做法是使用标准库中的std::lock和std::try_lock函数来对多个Lockable对象加锁。std::lock(或std::try_lock)会使用一种避免死锁的算法对多个待加锁对象进行lock操作(std::try_lock进行try_lock操作),当待加锁的对象中有不可用对象时std::lock会阻塞当前线程知道所有对象都可用(std::try_lock不会阻塞线程当有对象不可用时会释放已经加锁的其他对象并立即返回)。使用std::lock改写前面的代码,这里刻意让第6行和第13行的参数顺序不同

相关文章
|
8月前
|
安全 算法 程序员
|
5月前
|
监控 算法 安全
Java并发编程案例分析:死锁的检测与解决
Java并发编程案例分析:死锁的检测与解决
45 2
|
8月前
|
监控 算法 安全
Java并发编程案例分析:死锁的检测与解决
【4月更文挑战第6天】Java并发编程中的死锁导致线程僵持,资源无法释放,影响程序性能。死锁涉及互斥、请求与保持、不剥夺和循环等待四个条件。案例分析展示了银行转账场景下的死锁可能。检测死锁可通过日志、代码审查和使用工具。解决策略包括避免死锁(如设定锁顺序、超时机制)和处理死锁(如终止线程、资源抢占)。理解死锁原理并采取预防措施对构建稳定、高效的多线程应用至关重要。
142 1
什么是死锁?产生死锁的原因?产生死锁的四个必要条件?死锁的避免与预防?
什么是死锁?产生死锁的原因?产生死锁的四个必要条件?死锁的避免与预防?
388 0
|
8月前
|
安全 Java 测试技术
发生死锁怎么办
发生死锁怎么办
71 0
|
算法 安全
死锁的总结(2)
死锁的总结
52 0
|
安全 算法
死锁的总结(1)
死锁的总结
38 0
|
算法 安全 Java
死锁的原理
之前在学校学习过程中,很少写多进程的代码,虽然操作系统中学过死锁相关的内容,但考试过后也基本就忘记了,后来自己也遇到过有些多进程死锁的情况,再加上看了有些资料,对死锁才算是有了有些深入的理解。
92 0
|
算法 调度
死锁的理解
死锁的理解
93 0
|
SQL 关系型数据库 MySQL
死锁分析
最近新项目上线,在压测和发布生产都出现了好几种死锁情况,分析一二
210 0
死锁分析