给出一条语句“当CM空闲并从WCP接收更新请求时,它将设置...。” 。 某些上下文:通道中只能存在一种类型的味精,即仅包含来自wcp的更新请求。
我可以想到2种可能的实现。但是,我不太确定哪种方法正确。
第一种方式:
do
:: CM_STATUS == IDLE && nempty(wcpOut) -> // remove msg from channel and set something;
od;
第二种方式
mtype receivedMessage;
do
:: CM_STATUS == IDLE ->
if
:: wcpOut?receivedMessage -> // set something;
fi;
od;
答案 0 :(得分:1)
两个例子完全不同。
do
:: CM_STATUS == IDLE && nempty(wcpOut) -> // read msg
od;
在这里,如果您的状态为idle
并且频道wcpOut
不为空,则您承诺阅读该消息。但是,如果在评估nempty(wcpOut)
之前就抢占了该进程,并且该消息被其他人读取,会发生什么情况?在这种情况下,该过程可能最终被阻止。
mtype receivedMessage;
do
:: CM_STATUS == IDLE ->
if
:: wcpOut?receivedMessage -> // set something;
fi;
od;
在这里,您承诺在状态idle
时读取消息,因此直到读取消息后,您才能对状态变化做出反应。
除了简单的示例,我不会使用这两种方法。
第一种方法的缺点是它不能自动执行两个操作。第二种方法的缺陷在于,通过添加更多条件,很难扩展空闲state
中控制器的行为。 (例如,您将获得"dubious use of 'else' combined with i/o" error message if you tried to add an else
branch)。
恕我直言,更好的选择是
do
:: atomic{ nempty(my_channel) -> my_channel?receiveMessage; } ->
...
:: empty(my_channel) -> // do something else
od;
相反,当您想使用message filtering时,可以使用message polling:
do
:: atomic{ my_channel?[MESSAGE_TYPE] -> my_channel?MESSAGE_TYPE } ->
...
:: else -> // do something else
od;
您是否选择将这些条件与CM_STATUS == IDLE
一起使用还是您更愿意使用嵌套方法完全取决于您,除非您有理由相信CM_STATUS
变量可以被其他过程改变了。可以提高可读性时,我几乎总是使用第二种样式。