В вашем решении проблема в том, что сообщения изначально сортируются по sender
в точном порядке их создания, что также соответствует возрастающему порядку значений. Процесс reorder
в вашем образце модели, на самом деле, мало что дает. Он берет первое сообщение из очереди и помещает его в конец очереди. Если очередь содержит k
сообщений, после шагов k
сообщения снова сортируются в соответствии с первоначальным порядком.
Я вижу три возможных подхода к решению этой проблемы:
напрямую генерирует сообщения в случайном порядке, так что нет необходимости переупорядочивать их позже
помещает случайно сгенерированное начальное число в первое поле каждого сообщения и откладывает выполнение receiver
до тех пор, пока все сообщения не окажутся в очереди, чтобы при использовании случайным образом сообщения помещались в очередь сообщений. отсортировано отправить
использует случайный прием вместе с eval(idx)
, чтобы receiver
читал сообщения в случайном порядке, даже если сообщения в очереди идеально отсортированы. Это устраняет проблему синхронизации receiver
с sender
, но требует receiver
, чтобы узнать что-то больше о содержании сообщения, например, idx
каждого сообщения.
Решение, следующее за вторым подходом, описанным выше:
chan linkA = [10] of {byte, byte};
chan linkB = [10] of {byte, byte};
bool synch = false;
proctype sender ()
{
byte i;
byte idx;
for (i : 0 .. 5) {
int n = 2*i;
select(idx:0..255);
printf("Sender: <%d, %d> to linkA\n", idx, n*n);
linkA!!idx,n*n;
n = n + 1;
select(idx:0..255);
printf("Sender: <%d, %d> to linkB\n", idx, n*n);
linkB!!idx,n*n;
}
synch = true;
}
proctype receiver (chan link)
{
byte i, idx;
byte result[6];
/* wait until all messages in the queue */
synch;
for (i : 0 .. 5) {
link?idx,result[i];
printf("Receiver(%d): <%d, %d>\n", _pid, idx, result[i]);
}
}
init
{
run sender ();
run receiver (linkA);
run receiver (linkB)
}
Вывод:
~$ spin test.pml
Sender: <0, 0> to linkA
Sender: <3, 1> to linkB
Sender: <2, 4> to linkA
Sender: <1, 9> to linkB
Sender: <1, 16> to linkA
Sender: <0, 25> to linkB
Sender: <0, 36> to linkA
Sender: <0, 49> to linkB
Sender: <4, 64> to linkA
Sender: <2, 81> to linkB
Sender: <0, 100> to linkA
Sender: <0, 121> to linkB
Receiver(3): <0, 25>
Receiver(3): <0, 49>
Receiver(2): <0, 0>
Receiver(3): <0, 121>
Receiver(2): <0, 36>
Receiver(3): <1, 9>
Receiver(3): <2, 81>
Receiver(2): <0, 100>
Receiver(3): <3, 1>
Receiver(2): <1, 16>
Receiver(2): <2, 4>
Receiver(2): <4, 64>
4 processes created
Обратите внимание, что idx
генерируется случайным образом и что модель допускает выполнения, в которых каждое сообщение имеет различное значение idx
.