多线程:死锁

news2024/11/18 14:02:38

目录

死锁的条件

死锁的示例

死锁的预防与解决

死锁的检测

总结


死锁(Deadlock)是多线程或多进程环境中一种特定的状态,指的是两个或多个线程或进程在执行过程中,由于争夺资源而造成的一种相互等待的状态,导致它们无法继续执行下去。当出现死锁时,相关的线程或进程都处于阻塞状态,无法获得所需的资源。

有这么一个段子:这天你去面试,HR问你什么是死锁。这时你和HR说:你给我发offer,我就告诉你什么是死锁。那HR又说:你告诉我什么是死锁,我就给你发offer。于是就这么周而复始,HR和你都在等待对方松口,于是就形成了一个循环,这就是死锁状态。

段子中的死锁分析:

  1. 互斥条件:你和HR各自持有对方所需的东西(你的知识和HR的offer),双方都不能同时拥有。

  2. 保持并等待条件:你在等待HR发offer,而HR则在等待你讲解什么是死锁。两者都在持有自己所拥有的“资源”同时等待对方。

  3. 不剥夺条件:你已经持有的(对死锁的了解)无法被强制夺取,而HR的offer也无法被你强行获取。

  4. 循环等待条件:你和HR形成了一个循环:你等待HR,HR等待你,所以形成了一个死锁状态。


死锁的条件

为了了解死锁的本质,需要认识到死锁发生的必要条件,这通常被称为死锁的四个必要条件

  1. 互斥条件:至少有一个资源必须被一个线程占用,而此时此资源不能被其他线程占用。

  2. 保持并等待条件:一个线程至少持有一个资源,同时又在等待获取其他线程持有的资源。

  3. 不剥夺条件:已经分配给线程的资源,在未使用完之前,不能被其他线程强行夺取。

  4. 循环等待条件:存在一个线程的集合,线程 A 等待线程 B 持有的资源,线程 B 等待线程 C 持有的资源,线程 C 又等待线程 A 持有的资源。这构成了一个环路。


死锁的示例

考虑以下示例,说明死锁的发生:

#include <iostream>
#include <thread>
#include <mutex>

// 定义两个互斥锁
std::mutex mutexA;
std::mutex mutexB;

// 线程1
void thread1Func() {
    std::lock_guard<std::mutex> lockA(mutexA);
    std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟一些工作
    std::lock_guard<std::mutex> lockB(mutexB); // 可能会死锁
    std::cout << "Thread 1 acquired both locks" << std::endl;
}

// 线程2
void thread2Func() {
    std::lock_guard<std::mutex> lockB(mutexB);
    std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟一些工作
    std::lock_guard<std::mutex> lockA(mutexA); // 可能会死锁
    std::cout << "Thread 2 acquired both locks" << std::endl;
}

int main() {
    std::thread thread1(thread1Func);
    std::thread thread2(thread2Func);
    
    thread1.join();
    thread2.join();
    
    return 0;
}

在这个代码示例中,thread1Func 和 thread2Func 两个线程可能会在获取锁的过程中造成死锁。假设:

  • 线程1 先获取了 mutexA,然后尝试去获取 mutexB
  • 线程2 先获取了 mutexB,然后尝试去获取 mutexA

如果两个线程在此时同时获取了各自的锁,就会造成互相等待,形成死锁。


死锁的预防与解决

为了避免死锁,可以采取以下几种策略:

  1. 资源有序分配:通过按顺序请求资源,确保不会形成环路。例如,总是先请求 mutexA 再请求 mutexB

  2. 资源抢占:如果一个线程被阻塞,它所持有的资源可以被强制释放,允许其他线程获取资源。

  3. 超时机制:给资源请求设置一个超时时间,超过时间的话,放弃所占用的资源,稍后再尝试获取。

  4. 死锁检测和恢复:运行时监控系统状态,以发现和处理死锁。如果检测到死锁,可以通过终止某些线程或强制释放资源来恢复系统。


死锁的检测

在一些高级系统中,可以使用算法来检测死锁,如银行家算法、等待图和资源分配图等,以便找出死锁发生的根本原因并采取措施解决它。

总结

死锁是多线程编程中一个需要谨慎处理的问题,了解其发生的条件和预防策略能够帮助我们编写更为健壮和高效的代码。通过合理的资源管理和调度,可以有效减小甚至避免死锁的发生。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2162305.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微服务——配置管理

1.配置管理 微服务配置管理是指对微服务架构中各个服务的配置信息进行管理、更新、查询和审计等操作&#xff0c;以确保系统的正常运行和高效管理。例如&#xff0c;网关路由或某些业务配置在配置文件中写死了&#xff0c;每次修改都要重启服务。每个微服务都有很多重复的配置&…

6 门新兴语言,小众亦强大

​编码语言在塑造我们创建软件的方式方面起着至关重要的作用。多年来&#xff0c;我们观察到 Python&#xff0c;Java 和 C等成熟语言的流行。然而&#xff0c;如今一波新的编码语言浪潮已经出现&#xff0c;提出了创造性的解决方案&#xff0c;并推动了软件工程领域所能完成的…

【更新】全国地级市胡焕庸线、长江经济带、地域划分数据

本次数据是地级市的胡焕庸线、长江经济带、地域划分数据&#xff1a; 1、胡焕庸线是一条经典的地理分割线&#xff0c;它区分了中国人口分布的稠密区与稀疏区&#xff0c;东南部地区人口密集&#xff0c;西北部地区则较为稀疏 2、长江经济带是指沿长江流域分布的经济区域&…

聚焦Llama新场景和AR眼镜,扎克伯格用AI赋能元宇宙,Meta Connect 2024开发者大会即将开始

北京时间 9 月 26 日凌晨 1 点&#xff08;美国时间 9 月 25 日上午 10 点&#xff09;&#xff0c;Meta Connect 2024 年度开发者大会即将举行。 届时&#xff0c;Meta 首席执行官马克扎克伯格将聚焦 AI 和元宇宙&#xff0c;向大家分享 Meta 最新的产品和服务。HyperAI超神经…

微信小程序转化为uni-app项目

前言&#xff1a; 之前自己做一个uni-app的项目的时候前端需要实现一个比较复杂的动态tab和swiper切换的功能&#xff0c;但是由于自己前端抠脚的原因没有写出来&#xff0c;然后自己在网上搜索的时候发现了有个微信小程序里面的页面及极其的符合我的需求。那么问题来了我该如何…

《ESP32调试异常集锦》之:程序编译失败,提示undefined reference to `dedic_gpio_bundle_write‘

项目场景&#xff1a; 硬件&#xff1a;ESP32-LyraT-Mini V1.2开发板&#xff0c;使用的是ESP32-WROVER-E 模组。 程序&#xff1a;基于soft_i2c示例程序修改协议内容实现与TM1640通信测试 问题描述 编译失败&#xff0c;"full clean"后重新编译依旧失败。没有语法…

无法将“allure”项识别为 cmdlet、函数、脚本文件或可运行程序的名称的解决方法-allure的安装配置全过程

新手在使用allure之前&#xff0c;以为只是pip install allure-pytest就可以&#xff0c;no&#xff01;&#xff01;&#xff01; 其实&#xff0c;还需要下载allure&#xff0c;allure的具体步骤如下&#xff1a; 1.下载 allure。 allure的下载地址&#xff1a;Central Re…

解决你的IDE在使用的时候测试单元@Test在创建Scanner对象是键盘键入不了的问题;

插播一条快讯&#xff0c;我在我的ide中新创建 了project后发现我的测试单元不好使了&#xff0c;即 import org.junit.Test; 这个包在创建Scanner对象接受键盘时&#xff0c;控制台输入时没有任何反应&#xff0c;键入不了了&#xff0c;我的问题出现原因可能是我导入了JDBC…

基于SpringBoot+Vue的校园快递代取管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

Maven配置及使用

1. Maven简介和安装 1.1. Maven是一个依赖管理工具 问题&#xff1a; jar包的规模 随着使用框架越来越多&#xff0c;或框架的封装程度越来越高&#xff0c;项目中使用的jar包也越来越多。项目中&#xff0c;一个模块里用到上百个jar包是非常正常的jar包的来源 jar包所属技术…

力扣算法题总结

lc253 题目&#xff1a;求最多重叠(x,y)的数量 思路&#xff1a;按y排序&#xff0c;把y放入优先队列&#xff0c;逐个比较x&#xff0c;x大于优先队列的堆顶元素就弹出堆顶。 lc148 题目&#xff1a;对链表排序 思路&#xff1a;归并排序。快慢指针找到链表中点&#xff0c…

计算机网络详解:发展史、TCP/IP协议、网络通信与应用开发全流程

文章目录 1. 计算机网络的发展史1.1 初期阶段&#xff1a;网络的萌芽&#xff08;1960年代&#xff09;1.2 第二阶段&#xff1a;TCP/IP协议的引入&#xff08;1970-1980年代&#xff09;1.3 第三阶段&#xff1a;互联网的普及与商业化&#xff08;1990年代&#xff09;1.4 现代…

uniapp 动态修改input样式

最近在用HBuilderx工具开发蓝牙调试工具&#xff0c;项目采用uniapp、vue3.0架构&#xff0c;需求设计为在向蓝牙模块发送数据之前&#xff0c;监测input是否为空&#xff0c;如果为空&#xff0c;则input边框橙红色。界面如下图所示&#xff1a; uniapp架构采用 .vue格式文件&…

深入解析SGD、Momentum与Nesterov:优化算法的对比与应用

目录 1. 梯度下降算法2. BGD、SGD、MBGD3. momentum与dampening3.1 另一种形式的momentum3.1.1 学习率固定3.1.2 学习率不固定 4. nesterov4.1 PyTorch中的Nesterov4.2 Polyak与Nesterov的比较 Ref 1. 梯度下降算法 先考虑一元情形。假设待更新的参数为 θ \theta θ&#xf…

常见统计量与其抽样分布

什么是统计量 我们首先给出统计量的定义:设 X 1 , X 2 , ⋯ , X n X_1,X_2,\cdots,X_n X1​,X2​,⋯,Xn​ 为来自于总体X的一个样本&#xff0c; g ( X 1 , X 2 , ⋯ , X n ) g(X_1,X_2,\cdots,X_n) g(X1​,X2​,⋯,Xn​) 为关于 X 1 , X 2 , ⋯ , X n X_1,X_2,\cdots,X_n X…

React开发环境搭建以及常见错误解决

‌React开发环境搭建主要包括Node.js安装、编辑器选择、创建React项目等步骤‌。 Node.js安装‌ 从Node.js官网下载并安装最新版本的Node.js&#xff0c;安装过程中npm会自动安装。安装完成后&#xff0c;通过命令行输入node -v和npm -v检查安装是否成功。 carawang%node -v…

JS 特殊运算符有哪些?

JavaScript 特殊运算符有哪些&#xff1f; 众多编程语言之中JavaScript &#xff0c;以其强大而全面的功能深受前端开发者喜爱。其丰富的运算符集&#xff0c;不仅包括了广泛应用的算术运算符、比较运算符以及逻辑运算符&#xff0c;还蕴藏着一系列较为冷门但同样功能强大的运算…

【SSM-Day2】创建SpringBoot项目

运行本篇中的代码&#xff1a;idea专业版或者idea社区版本&#xff08;2021.1~2022.1.4&#xff09;->这个版本主要是匹配插件spring boot Helper的免费版(衰) 【SSM-Day2】创建SpringBoot项目 框架->Spring家族框架快速上手Spring Boot&#x1f4e2;用idea插件创建Sprin…

python文件读写知识简记

简单记录一下python文件读写相关知识 一、打开文件 python使用open函数打开文件&#xff0c;函数原型如下 open(file, moder, buffering-1, encodingNone, errorsNone, newline None, closefdTrue, openerNone) file 文件地址 mode 文件打开模式&#xff0c;可设定为如下的…