我目前正在解决的问题需要使用两个或更多锁(在这种情况下为文件锁)以避免并发问题。
但是我无法代表我将用于解决方案的(锁定)模型。
即。我想通过某种类型的图表来解释问题和我正在编码的解决方案,它允许我显示锁定序列,并发性含义(例如,如果我们在此之前释放此锁定,我们将遇到此问题,等等)和其他此类有用的信息。
表示锁定模型的好方法是什么?
我一方面试图用流程图这样做,所以我可以显示导致我必须获得锁定的代码流(例如我使用独有的非阻塞锁来确定是否一个进程已经在监视一个文件,如果没有我启动监视器),另一方面我一直在想序列图会这样做,但我对结果不满意。
是否还有其他可视工具可以让我代表这个问题?
工程师如何为分布式系统等真正复杂的问题解决这个问题?
是否有任何一个图表,或者它更像是用于描述此图表的图表集合?
答案 0 :(得分:2)
Petri nets用于建模并发(和并发分布式系统)。作为一个正式的数学概念,它们允许您推理操作序列,状态可达性(例如用于证明永远不会发生锁和/或资源状态的不可接受的配置),活跃性,有界性,死锁和其他此类有用信息。此外,他们有清晰的视觉表现。 但是使用Petri网必须使用低级别的概念,比如场所和过渡,并且没有办法进行抽象建模。因此,即使对于中等大小的问题,它们的视觉描绘通常也会变得很大。彩色,优先级,定时和其他增强的Petri网有时会拯救,但对于更复杂的抽象系统UML statecharts更适合。
以下是使用Petri网进行锁定序列分析的一些示例(有关详细信息,请参阅出版物):
答案 1 :(得分:1)
对于非常复杂的无锁算法验证,没有这样的可视化有助于证明其正确性。相反,有一些工具可用于多线程软件应用程序的形式验证。
E.g。请查看Spin,它旨在验证并发执行的线程的每个组合。 Spin的这种模型的一个例子如下:
// a small example spin model
// Peterson's solution to the mutual exclusion problem (1981)
bool turn, flag[2]; // the shared variables, booleans
byte ncrit; // nr of procs in critical section
active [2] proctype user() // two processes
{
assert(_pid == 0 || _pid == 1);
again:
flag[_pid] = 1;
turn = _pid;
(flag[1 - _pid] == 0 || turn == 1 - _pid);
ncrit++;
assert(ncrit == 1); // critical section
ncrit--;
flag[_pid] = 0;
goto again
}
// analysis:
// $ spin -a peterson.pml
// $ cc -o pan pan.c
// $ ./pan
在这里,您将描述线程如何通信以及定义预期程序状态的条件。如果任何可能的执行组合导致断言失败,它将与导致它的控制流一起报告。
答案 2 :(得分:1)
我应该已经开始使用多个UML序列图(每个争用案例一个),巧妙地使用标记(颜色,注释,片段,OCL)。
以前的实时系统设计有很多时序图。但我不习惯。
大多数时候,我对我的代码有一个很好的思维导图,我问自己每个指令,如果此时有任何线程正在运行会发生什么,禁止状态是什么。它与Design by contract非常相似(通过"标记"可以显示在序列图上的合同。
每次我使用并发代码时,如果设计得很好,您只关注关键片段(仅限于几行代码)。
答案 3 :(得分:1)
描述这种锁定微体系结构可能需要两个或三个关于该机制的视图。一个可能是状态图(这是一个示例,优雅地说明了Java 6线程状态和生命周期)Thread States。
序列图可能会说明监视器的轮询行为 - 假设您的监视器正在序列化资源访问并授予多个读取锁以读取请求,但可以单独访问写入请求。在这种情况下,您可以说明如果有未完成的读取请求,则写入请求将被阻止,直到所有读取完成 - 同时仍显示写入请求按优先级顺序排队,以便无限期等待。 (对不起,我对你的算法做了很多假设,但许多悲观算法都以这种方式运行)。
最后,UML泳道图可以很好地显示各种代理的并发活动 - 读取和写入请求,监视器等。
我在软件架构上发现的最好的书之一是"Documenting Software Architectures, Views and Beyond" 。你会发现它值得你花时间(恕我直言)。
干杯!精彩的问题!