如何从PROMELA / SPIN中的“任意”频道接收消息

时间:2012-03-28 17:40:45

标签: spin

我在Spin中建模算法。 我有一个有多个频道的进程,在某些时候,我知道会有一条消息,但不知道从哪个频道。所以想等待(阻止)进程,直到消息来自任何通道。我怎么能这样做?

2 个答案:

答案 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循环不确定地选择0NUMCHAN-1之间的索引,并从相应的渠道读取,如果有东西要读,否则此渠道是总是跳过。当然,在使用Spin进行模拟时,从通道NUMCHAN读取的概率远小于通道0的概率,但这对于模型检查没有任何影响,其中探索了任何可能的路径。 / p>