2、死锁建模:资源分配图(RAG)的构成、如何用RAG表示系统状态、RAG的简化与化简

好,咱们进入正题。死锁这东西,光靠脑子想容易乱。你想想看,系统里几十个任务、上百种资源,谁等谁、谁占着啥,光靠日志去排查,头都大了。所以我们需要一个工具——资源分配图(Resource Allocation Graph,简称RAG)。说白了,它就是一张“谁占着啥、谁想要啥”的关系图。

2.1 RAG的构成:节点与边

RAG的构成其实特别简单,就两种节点、两种边。我刚开始学的时候,觉得这玩意儿不就是个有向图嘛。嗯,确实就是有向图,但它的语义很关键。

  • 进程节点:用圆圈表示,里面写进程名,比如P1、P2。代表系统里的任务或线程。
  • 资源节点:用方框表示,里面写资源名,比如R1、R2。方框里的小圆点代表资源的实例数量。比如一个打印机资源,方框里就画一个点;如果有两台同型号打印机,就画两个点。
  • 请求边:从进程节点指向资源节点的有向边。表示“进程P1正在申请一个R1资源”。
  • 分配边:从资源节点指向进程节点的有向边。表示“资源R1的一个实例已经分配给了进程P1”。

关键点:请求边和分配边的方向是相反的。请求边是进程→资源,分配边是资源→进程。千万别搞反了,我在项目评审时见过有人画反,结果整个分析全错了。

2.2 如何用RAG表示系统状态

一张RAG图,就是系统在某个时刻的“快照”。它完整地描述了:哪些资源被谁占着,哪些进程在等什么资源

举个例子。假设系统里有:

  • 进程P1:占着R1(一个实例),同时申请R2。
  • 进程P2:占着R2(一个实例),同时申请R1。

画成RAG就是:

   P1 ——请求边——→ R2
    ↑                ↓
    R1 ←——分配边—— P2

你看,这形成了一个环。有环不一定死锁,但在这个例子里,每个资源只有一个实例,而且环上的每个进程都在等环上另一个进程释放资源——这就是典型的死锁状态。

我个人习惯,在分析复杂系统时,会先画出RAG,然后盯着环看。为什么?因为死锁的必要条件之一就是“循环等待”,而环就是循环等待的直观体现。

避坑指南:我曾经在一个多核通信项目中,用RAG分析共享内存的分配情况。画完图发现有个四进程的环,但当时系统没死锁。后来仔细一看,其中一个资源有多个实例,环上的进程其实可以走别的路径拿到资源。所以记住:有环不一定死锁,但无环一定不死锁

2.3 RAG的简化与化简

RAG画出来了,怎么判断系统是否处于死锁状态?这就需要化简。化简的过程,说白了就是模拟资源释放和分配,看看能不能把所有进程都“解开”。

化简步骤

  1. 找一个“不阻塞”的进程:这个进程当前申请的资源都能被满足(即它的所有请求边都能找到空闲资源实例)。
  2. 让这个进程运行完毕并释放资源:把它占用的所有资源实例归还,删除它的所有分配边和请求边。
  3. 重复步骤1和2,直到所有进程的边都被删除,或者找不到不阻塞的进程。

如果所有进程的边都能被删除,说明系统是可化简的,即没有死锁。如果最后还剩下一部分进程的边删不掉,那这些进程就是死锁进程

注意:化简的顺序不影响最终结果。你先化简P1还是P2,最后剩下的死锁进程集合是一样的。这一点我亲自验证过,你可以放心。

一个化简的例子

假设系统状态如下:

  • 资源R1有1个实例,已分配给P1。
  • 资源R2有1个实例,已分配给P2。
  • P1申请R2,P2申请R1。

化简过程:

  1. 检查P1:它申请R2,但R2被P2占着,不满足。阻塞。
  2. 检查P2:它申请R1,但R1被P1占着,不满足。阻塞。
  3. 找不到不阻塞的进程,化简结束。P1和P2都是死锁进程。

你看,这就是典型的死锁。如果R1或R2有多个实例,情况就不同了。比如R1有2个实例,一个给了P1,另一个空闲。那么P2申请R1时就能满足,P2运行完释放R2,P1也能继续——整个图就化简干净了。

我曾经踩过的坑:有一次在嵌入式系统中,我通过RAG化简判断系统没有死锁,但实际跑起来却卡死了。后来发现,我忽略了资源释放的顺序。RAG化简假设进程会一次性释放所有资源,但实际代码中,进程可能先释放一部分资源,再申请新的资源。这种情况下,RAG的静态分析就不够用了,需要结合资源请求序列来做动态分析。所以,RAG化简是基础,但不是万能的。

2.4 小结

RAG是死锁分析的“第一性原理”。它把复杂的资源竞争关系,变成了一张看得见的图。你只要记住:

  • 圆圈是进程,方框是资源。
  • 请求边指向资源,分配边来自资源。
  • 化简就是模拟释放,删不掉的边就是死锁。

下一章,咱们会深入讨论死锁的四个必要条件,以及如何在实际工程中利用RAG来设计死锁避免策略。嗯,到时候我会分享一个我亲手做过的案例,保证让你有收获。