【Linux】死锁四条件的底层逻辑:从锁冲突到 STL 组件的线程安全实践(Ⅵ)

一、死锁概念

死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所占用不会释放的资源而处于的一种永久等待状态。

为了方便表述,假设现在线程A,线程B必须同时持有锁1和锁2,才能进行后续资源的访问:

申请一把锁是原子的,但是申请两把锁就不一定了:

造成的结果是:

二、死锁的四个必要条件

互斥条件:一个资源每次只能被一个执行流使用。说人话就是使用了锁。

请求与保持条件:一个执行流因请求资源而阻塞时,对已获得的资源保持不放。

**不剥夺条件:**一个执行流已获得的资源,在末使用完之前,不能强行剥夺。

**循环等待条件:**若干执行流之间形成一种头尾相接的循环等待资源的关系:

三、避免死锁问题

破坏死锁的四个必要条件,例如:不使用锁,破坏互斥条件,在申请锁时,使用:

cpp 复制代码
pthread_mutex_trylock(&mutex)

申请失败不会阻塞在哪里,我们可以使用这个函数去申请锁,如果失败了,让该线程释放锁,进而再申请锁,破坏请求与保持条件;使用:资源一次性分配、使用超时机制、加锁顺序来,破坏循环等待条件,也可以使用C++的 std::lock 函数来破坏循环等待条件,原理是:同时申请多个锁成功才能访问对应的资源;

四、STL、智能指针和线程安全

问题:STL中的容器是否是线程安全的?

答:不是,原因:STL的设计初衷是将性能挖掘到极致,而一旦涉及到加锁保证线程安全,会对性能造成巨大的影响,而且对于不同的容器,加锁方式的不同,性能可能也不同(例如hash表的锁表和锁桶),因此STL默认不是线程安全.如果需要在多线程环境下使用,往往需要调用者自行保证线程安全。

问题:智能指针是否是线程安全的?

答:对于 unique_ptr,由于只是在当前代码块范围内生效,因此不涉及线程安全问题,对于 shared_ptr,多个对象需要共用一个引用计数变量,所以会存在线程安全问题,但是标准库实现的时候考虑到了这个问题,基于原子操作(CAS)的方式保证shared_ptr 能够高效,原子的操作引用计数。


相关推荐
wj3055853788 小时前
课程 9:模型测试记录与 Prompt 策略
linux·人工智能·python·comfyui
abigriver9 小时前
打造 Linux 离线大模型级语音输入法:Whisper.cpp + 3090 显卡加速与 Rime 中英混输终极调优指南
linux·运维·whisper
wangqiaowq9 小时前
windows下nginx的安装
linux·服务器·前端
YYRAN_ZZU10 小时前
Petalinux新建自动脚本启动
linux
charlie11451419110 小时前
嵌入式Linux驱动开发pinctrl篇(1)——从寄存器到子系统:驱动演进之路
linux·运维·驱动开发
Agent手记10 小时前
异常考勤智能预警与处理与流程优化方案 | 基于企业级Agent的超自动化实战教程
运维·人工智能·ai·自动化
于小猿Sup10 小时前
VMware在Ubuntu22.04驱动Livox Mid360s
linux·c++·嵌入式硬件·自动驾驶
cen__y10 小时前
Linux12(Git01)
linux·运维·服务器·c语言·开发语言·git
不仙52012 小时前
VMware Workstation 26.0.0 在 Ubuntu 24.04 (内核 6.17.0) 上的安装与内核模块编译问题
linux·ubuntu·elasticsearch
小小编程路12 小时前
C++ 多线程与并发
java·jvm·c++