浅谈死锁

本文探讨了死锁的概念,即两个以上进程因资源竞争而陷入无限等待的现象。阐述了死锁的常见情况,包括同一线程两次加锁和线程间的环路等待。资源分为可剥夺和不可剥夺,死锁的必要条件包括互斥、不可抢占、请求和保持、环路等待。介绍了判断和避免死锁的方法,如鸵鸟算法、预防死锁(破坏请求和保持、环路等待条件)、避免死锁的银行家算法,以及检测和解除死锁的策略。

什么死锁:
是两个或者两个以上的进程由于竞争资源而造成的的一种相互等待的线性,如无外力作用,这些进程将永远不能再向前推进。
陷入死锁状态的进程称为死锁进程,所占用的资源或者需要他们进行某种合作的进程就会相继陷入死锁,最终可能导致整个系统瘫痪

死锁的常见情形:
一般情况下,如果同一个线程先后两次调用lock,在第二次调用时,由于锁已经被占用,该线程会挂起等待别的线程释放锁,然而锁正是被自己占用着的,该线程又被挂起而没有机会释放锁, 因此 就永远处于挂起等待状态了,这叫做死锁(Deadlock)。但只有一个线程一般情况下是不会去加锁的。

另一种典型的死锁情形是这样:线程A获得了锁1,线程B获得了锁2,这时线程A调用lock试图获得锁2,结果是需要挂起等待线程B释放锁2,而这时线程B也调用lock试图获得锁1,结果是需要挂起等待线程A释放锁1,于是线 程A和B都 永远处于挂起状态了。这样就是一个环路等待,产生了死锁。

资源的分类:
根据资源的性质:可剥夺(抢占)和不可剥夺(抢占)资源
可抢占资源:一资源占有进程虽然需要使用该资源,但另一个进程却强行把资源从占有进程中抢占过来。(cpu,主存,硬盘)
不可抢占资源;除了占有进程主动释放资源外,其他进程不得在占有进程使用资源的时候强行抢占。(打印机,读卡器)

产生死锁的必要条件:
1、互斥条件:
一个进程一次只能被一个进程所使用
2、不可抢占条件:
一个资源仅能被它的占有进程所释放,不能被别的进程抢占。
3、请求和保持条件:
进程至少已经保持了至少一个资源,但又提出了新的资源要求,而该资源又被其他进程所占用,此时请求进程阻塞,但是又对它已经获得的资源部释放,此时别的进程如果申请它的资源就也会出现阻塞。
4、环路等待条件:
当每类资源只有一个的时候,在发生死锁的时候,必然会出现一个资源的环形链。P1在等待P2占有的一个资源S2,P2在等待P1占有的一个资源S1;

看资源分配图判断是否发生死锁
看是

### 串口通讯协议设计规范与最佳实践 #### 设计规范 串口通信作为一种常见的数据传输方式,在硬件和软件层面都需要遵循一定的设计规范,以确保系统的可靠性和稳定性。 1. **波特率设置** 波特率决定了每秒传输的数据位数。为了保证双方设备之间的同步性,必须严格匹波特率参数[^2]。通常情况下,常用的波特率为9600、115200等标准化数值。 2. **数据帧结构** 数据帧由起始位、数据位、奇偶校验位(可选)、停止位组成。具体置如下: - 起始位:固定为低电平,表示一帧数据的开始。 - 数据位:一般为7到8位,取决于实际需求。 - 奇偶校验位:用于检测传输错误,可以选择无校验、奇校验或偶校验。 - 停止位:高电平持续间,可以是一倍或多倍于比特周期。 3. **超机制** 在长间未接收到有效数据,应引入超机制来防止死锁现象的发生。这可以通过定器实现,并结合事件驱动模型提升程序响应效率[^1]。 4. **流控策略** 实现软硬件握手功能非常重要。常用的方法包括XON/XOFF字符控制或者RTS/CTS信号线管理流量方向及速率调整。 #### 最佳实践 除了基本的设计原则之外,还有一些经过验证的最佳实践经验可以帮助优化整个过程: 1. **CRC校验增强可靠性** 循环冗余检验(CRC)算法被广泛应用于保障消息完整性方面。特别是在噪声环境较为恶劣件下尤为必要[^2]。 2. **采用异步模式减少耦合度** 使用UART这样的通用异步接收发送装置(UART),可以在不依赖外部钟源的前提下完成高效的信息交换操作[^4]。 3. **模块化编码提高维护便利性** 将复杂的逻辑分解成独立的功能单元分别处理,比如初始化函数单独封装;读写操作各自定义接口形式等等做法均有利于后期升级迭代工作开展顺利进行下去。 4. **充分考虑边界件测试覆盖范围广** 对极端情况下的行为表现给予特别关注,例如缓冲区溢出保护措施安排合理与否直接影响整体性能指标达成效果如何评估等问题都要仔细考量清楚才行。 ```python import serial from time import sleep def init_serial(port='/dev/ttyUSB0', baudrate=115200, timeout=1): ser = serial.Serial( port=port, baudrate=baudrate, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=timeout ) if not ser.is_open: raise Exception(f"Failed to open {port}") return ser def send_data(ser, data): try: ser.write(data.encode()) sleep(0.1) # Allow some delay for transmission except Exception as e: print(e) def read_response(ser): response = "" while True: byte = ser.read().decode('utf-8') if not byte or byte == '\n': break response += byte return response.strip() ``` 以上代码片段展示了如何利用Python中的`pyserial`库创建一个单的串口通信应用程序实例。其中包括了端口打开、数据发送以及响应读取等功能部分演示说明[^2]。 #### 标准参考 不同领域可能会有不同的特定要求和技术规格书可供查阅学习借鉴之处很多。例如工业自动化场景下经常涉及到Modbus RTU/TCP协议栈构建任务就需要参照官方文档指南执行相应步骤动作序列组合起来形成最终解决方案成果展示出来供大家交流讨论共同进步成长壮大队伍规模扩大影响力范围延伸出去影响更多人群受益匪浅值得推荐尝试一下看看效果怎样再做进一步改进完善细节方面的不足之处加以弥补修正过来达到预期目标为止结束本次话题分享环节谢谢大家的支持合共同努力创造美好未来前景无限光明灿烂辉煌明天等着我们一起去开创属于自己的传奇故事篇章吧! ---
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值