我在Spin中建模算法。 我有一个有多个频道的进程,在某些时候,我知道会有一条消息,但不知道从哪个频道。所以想等待(阻止)进程,直到消息来自任何通道。我怎么能这样做?
答案 0 :(得分:3)
我认为你需要Promela的构造(参见http://spinroot.com/spin/Man/if.html)。
在您指的过程中,您可能需要以下内容:
byte var;
if
:: ch1?var -> skip
:: ch2?var -> skip
:: ch3?var -> skip
fi
如果没有任何一个频道,那么"选择结构作为一个整体阻止" (引用手册),这正是你想要的行为。
更全面地引用手册的相关部分: "只有当其guard语句可执行时,才能选择[每个:: lines]选项执行[guard语句是 - >]之前的部分。如果可执行多个保护语句,则将非确定性地选择其中一个保护语句。如果没有一个守卫是可执行的,那么选择结构将作为一个整体阻止。"
顺便说一下,我还没有在Spin中检查或模拟上面的语法。希望它是对的。我对Promela和Spin非常陌生。
答案 1 :(得分:0)
如果您想让您的通道数变量而不必更改发送和接收部件的实现,您可以使用以下生产者 - 消费者示例的方法:
#define NUMCHAN 4
chan channels[NUMCHAN];
init {
chan ch1 = [1] of { byte };
chan ch2 = [1] of { byte };
chan ch3 = [1] of { byte };
chan ch4 = [1] of { byte };
channels[0] = ch1;
channels[1] = ch2;
channels[2] = ch3;
channels[3] = ch4;
// Add further channels above, in
// accordance with NUMCHAN
// First let the producer write
// something, then start the consumer
run producer();
atomic { _nr_pr == 1 ->
run consumer();
}
}
proctype consumer() {
byte var, i;
chan theChan;
i = 0;
do
:: i == NUMCHAN -> break
:: else ->
theChan = channels[i];
if
:: skip // non-deterministic skip
:: nempty(theChan) ->
theChan ? var;
printf("Read value %d from channel %d\n", var, i+1)
fi;
i++
od
}
proctype producer() {
byte var, i;
chan theChan;
i = 0;
do
:: i == NUMCHAN -> break
:: else ->
theChan = channels[i];
if
:: skip;
:: theChan ! 1;
printf("Write value 1 to channel %d\n", i+1)
fi;
i++
od
}
消费者流程中的do
循环不确定地选择0
和NUMCHAN-1
之间的索引,并从相应的渠道读取,如果有东西要读,否则此渠道是总是跳过。当然,在使用Spin进行模拟时,从通道NUMCHAN
读取的概率远小于通道0
的概率,但这对于模型检查没有任何影响,其中探索了任何可能的路径。 / p>