如何在没有超时/死锁的情况下在PROMELA进程中发送和接收?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在没有超时/死锁的情况下在PROMELA进程中发送和接收?相关的知识,希望对你有一定的参考价值。
我无法解决这个PROMELA问题:我有N个进程(“pc”),它们可以通过一个通道发送和接收消息(“to_pc”)。每个进程都有自己的通道,通过它接收消息。对于能够接收的进程,我必须将其保持在循环中,该循环检查通道中的传入消息。作为第二个循环选项,该过程向所有其他通道发送消息。
但是,在模拟模式下,这总是会导致超时,而根本不会发送任何内容。到目前为止,我的理论是,我创建了一个死锁,所有进程都想立即发送,导致所有进程都无法接收(因为它们被卡在代码的“发送”部分)。
到目前为止,我一直无法解决这个问题。我试图使用全局变量作为信号量来“禁止”发送,因此只有一个频道可以发送。但是,这并没有改变结果。我唯一的另一个想法是使用超时作为发送的触发器,但这对我来说似乎不对。
有任何想法吗?提前致谢!
#define N 4
mtype={request,reply}
typedef message {
mtype type;
byte target;
byte sender;
};
chan to_pc[N] = [0] of {message}
inline send() {
byte j = 0;
for (j : 0 .. N-1) {
if
:: j != address ->
to_pc[j]!msg;
:: else;
fi
}
}
active [N] proctype pc(){
byte address = _pid;
message msg;
do
:: to_pc[address]?msg -> /* Here I am receiving a message. */
if
::msg.type == request->
if
:: msg.target == address ->
d_step {
msg.target = msg.sender
msg.sender = address;
msg.type = reply;
}
send();
:: else
fi
:: msg.type == reply;
:: else;
fi
:: /* Here I want to send a message! */
d_step {
msg.target = (address + 1) % N;
msg.sender = address;
msg.type = request;
}
send();
od
};
如果你愿意,我可以编写一个完整的源代码工作版本,但也许它足以突出你正在处理的问题的来源,并让你有乐趣解决它。
分支规则
- 任何具有可执行条件的分支都可以非确定性地进行
- 如果没有具有可执行条件的分支,则采用else分支
- 如果没有具有可执行条件的分支且没有其他分支,则该过程将挂起,直到其中一个条件变为真
考虑一下
1: if
2: :: in?stuff -> ...
3: :: out!stuff -> ...
4: fi
其中in
和out
都是同步通道(大小是0
)。
然后
- 如果有人发送
in
的另一端,那么in?stuff
是可执行的,否则它不是 - 如果有人在
out
的另一端接收,那么out!stuff
是可执行的,否则它不是 - 该过程在
1:
行阻塞,直到两个条件中的至少一个可执行为止。
将该代码与此进行比较
1: if
2: :: true -> in?stuff; ...
3: :: true -> out!stuff; ...
4: fi
其中in
和out
再次是同步通道(大小是0
)。
然后
- 两个分支都有可执行条件(
true
) - 通过非确定性地选择在
2:
或3:
行执行分支,该过程立即承诺发送或接收某些内容 - 如果进程选择
2:
然后阻塞,如果in?stuff
不可执行,即使out!stuff
可执行 - 如果进程选择
3:
然后阻塞,如果out!stuff
不可执行,即使in!stuff
可执行
您的代码属于后一种情况,因为d_step { }
中的所有指令都是executable,并且您的进程承诺过早发送。
总结一下:为了修复你的模型,你应该重构你的代码,以便始终可以从发送模式跳转到接收模式,反之亦然。提示:摆脱内联代码,将实际发送的决定分开。
以上是关于如何在没有超时/死锁的情况下在PROMELA进程中发送和接收?的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有超时的情况下在 Travis CI 上安装一些东西?
事务 ( 进程 ID 60) 与另一个进程被死锁在锁资源上,并且已被选作死锁牺牲品。请重新运行 该事务。