我正在用Promela制作模型,我需要等待2个过程结束才能继续。如何用Promela做到这一点?
答案 0 :(得分:3)
首先:理论回顾。
在Promela中,进程 到达其代码末尾即结束,即
active proctype example()
{
/* some code */
/* here it ends */
}
进程结束后,就可以被系统终止了。被终止意味着以下事情:
_pid
已释放,现在可以由以后实例化的任何其他 new 流程重新使用。但是,请注意在进程终止时存在一些约束:
p_i
处于结束状态且没有其他进程p_j
且其_pid
的值大于p_i
的值时才终止它还活着。换句话说,只能按照创建过程的相反顺序终止进程,如docs所示。
此限制很重要,因为在Spin
中,在任何给定时刻最多只能有255
个进程同时处于活动状态。用run
生成大量进程的任何尝试都会被阻止,除非与此同时一些现有进程已正确终止以为新进程腾出空间。
第二:加入。
现在,要实现join
操作,我们首先必须确定这样做的意义:
join
应该在另一个进程执行到某个end state
时捕获。join
应该捕获到另一个进程有效终止并由系统释放其资源的时间示例:案例1)
第一种情况绝对易于设计和实现。我们只需在进程之间使用某种 synchronization 机制,以通知已达到给定的end state
。
这可以通过多种方式完成,具体取决于您要建模的行为风格的种类。这是一个可能的实现:
mtype = { END };
proctype do_something(chan out)
{
printf("proc[%d]: doing something ...\n", _pid);
end:
out!_pid, END;
}
init {
chan in = [5] of { mtype };
pid pids[5];
byte idx;
/* atomic{} is optional here */
atomic {
for (idx: 0 .. 4) {
pids[idx] = run do_something(in);
}
printf("init: initialized all processes ...\n");
}
/* join section */
for (idx: 0 .. 4) {
in??eval(pids[idx]), END;
printf("init: joined process %d ... \n", pids[idx]);
}
}
示例:案例2)
第二种情况的建模有点复杂,并且,据我所知,它可能有一些局限性,在某些设计下并不完全可行。
此方法依赖于变量_nr_pr
的值,该变量是一个预定义的全局只读变量,用于记录当前正在运行的进程数。
一个可以:
A。逐一加入我们以相反的创建顺序生成的所有过程
proctype do_something()
{
printf("proc[%d]: doing something ...\n", _pid);
end:
/* nothing to do */
}
init {
pid pids[5];
byte idx;
/* atomic{} is optional here */
atomic {
for (idx: 0 .. 4) {
pids[idx] = run do_something();
}
printf("init: initialized all processes ...\n");
}
/* join section */
for (idx: 0 .. 4) {
(_nr_pr <= pids[4 - idx]);
printf("init: joined process %d ... \n", pids[4 - idx]);
}
}
B 。加入我们一次生成的所有进程
proctype do_something()
{
printf("proc[%d]: doing something ...\n", _pid);
end:
/* nothing to do */
}
init {
pid pids[5];
byte idx;
/* atomic{} is optional here */
atomic {
for (idx: 0 .. 4) {
pids[idx] = run do_something();
}
printf("init: initialized all processes ...\n");
}
/* join section */
(_nr_pr <= pids[0]);
printf("init: all children terminated ... \n");
}