面试题答案
一键面试死锁区别
- 传统并发编程环境:
- 资源竞争类型:通常围绕进程或线程共享的本地资源,如内存、文件句柄、锁等。例如多个线程竞争访问同一个文件描述符进行读写操作。
- 死锁范围:局限于单个进程或同一主机内的多个进程之间,死锁检测相对简单,因为可以直接访问和监控所有相关资源和线程状态。
- 分布式系统环境:
- 资源竞争类型:涉及到跨网络的资源,如分布式数据库中的锁、远程服务调用资源等。例如不同节点上的进程竞争分布式锁服务中的锁资源。
- 死锁范围:跨多个节点和网络,由于网络延迟、节点故障等不确定性因素,死锁检测和预防更为复杂。节点之间难以实时准确获取彼此资源状态。
死锁检测和预防策略
- 传统并发编程环境:
- 检测策略:
- 资源分配图算法:通过构建资源分配图,检测图中是否存在环,若存在环则可能存在死锁。例如,在操作系统的进程管理中,可以利用这种方法检测多个进程之间的资源竞争关系。
- 预防策略:
- 破坏死锁的四个必要条件:
- 破坏互斥条件:尽量使用可共享资源,减少对互斥资源的依赖。但有些资源本身特性决定必须互斥访问,所以该方法应用有限。
- 破坏占有并等待条件:进程在申请新资源前,先释放已占有的资源。例如在数据库事务中,事务开始时获取所有需要的锁,避免在持有部分锁时再申请其他锁。
- 破坏不可剥夺条件:允许操作系统在必要时剥夺进程占有的资源分配给其他进程。例如当一个高优先级进程需要资源时,可以剥夺低优先级进程持有的资源。
- 破坏循环等待条件:对资源进行排序,进程按照顺序申请资源。例如在多线程程序中,对多个锁进行编号,线程按照编号从小到大的顺序获取锁。
- 破坏死锁的四个必要条件:
- 检测策略:
- 分布式系统环境:
- 检测策略:
- 分布式死锁检测算法:如 Chandy - Lamport 算法,它通过分布式的方式收集各个节点的资源和进程状态信息,构建全局资源分配图来检测死锁。该算法在节点间传递消息,标记资源和进程状态,以确定是否存在死锁环。
- 预防策略:
- 资源分配策略:使用分布式锁服务,如 ZooKeeper。通过 ZooKeeper 的特性,实现资源的有序分配,避免循环等待。例如在分布式文件系统中,使用 ZooKeeper 来管理文件锁,确保不同节点按照一定顺序获取锁。
- 超时机制:为资源请求和远程调用设置合理的超时时间。若在规定时间内未获取到资源或调用未完成,则放弃当前操作并释放已占有的资源。例如在微服务架构中,服务间调用设置超时,防止因网络问题导致长时间等待资源造成死锁。
- 检测策略:
分布式网络服务中避免死锁示例
假设一个分布式电商系统,其中订单服务、库存服务和支付服务可能会相互调用。例如订单服务创建订单时需要调用库存服务扣减库存,调用支付服务进行支付。为避免死锁:
- 资源排序:对这三个服务涉及的资源进行排序,假设顺序为库存服务资源 < 支付服务资源 < 订单服务资源。当订单服务发起操作时,先获取库存服务资源(扣减库存),再获取支付服务资源(进行支付),最后处理订单服务自身相关资源(创建订单记录)。其他服务调用时也遵循此资源获取顺序,避免循环等待。
- 超时机制:在订单服务调用库存服务和支付服务时,设置合理的超时时间。比如调用库存服务扣减库存,若 5 秒内未响应成功,则订单服务放弃操作并通知库存服务释放已锁定的库存资源,避免因库存服务故障或网络延迟导致死锁。