Ada:受保护条目的select / else语句。它有什么作用?

时间:2014-09-04 09:35:19

标签: ada

我对Ada有疑问,尤其是与受保护条目一起使用时的select语句。我们来考虑以下代码片段:

     select
        Protected_Object.Some_Entry;
     else
        DoSomethingElse;
     end select;

我的问题很简单:当达到select语句时,会发生什么?特别是,我想知道的是:只有当Some_Entry的后卫被关闭时才会选择其他分支,或者即使防护被打开但是该条目被占用了#34; (即:已经调用Some_Entry执行)因此无法立即调用??

2 个答案:

答案 0 :(得分:3)

我相信只有当条目的守卫关闭时才会选择else分支(即障碍条件为false)。受保护的条目呼叫的事件序列由RM 9.5.3(8)给出:

  • 在对象上启动新的受保护操作。

  • 检查命名条目以查看它是否已打开(即屏障条件为true);如果打开,则表示入口调用立即,然后执行入口正文。

如果另一个任务正在对同一个对象执行受保护的操作,则启动受保护的操作可能会涉及短暂的延迟(9.5.1(4))。但是,目的是这个延迟总是非常短。如果受保护的子程序或条目执行任何可能阻止程序的操作,则将其视为错误(9.5.1(8-18))。因此,等到另一个任务释放受保护对象应该是一个非常短的等待,如果有的话;在多处理器系统上,通过旋转(基本上是while Protected_Object_Is_In_Use(Obj) loop null; end loop;)而不是等待队列来实现这种等待是完全可以接受的。

因此,我对9.5.3(8)的解读是,“立即选择”的定义考虑到如果另一项任务涉及受保护的行动所需的短暂等待宾语。如果任务必须等待,它就会这样做。如果,一旦它能够抓住该对象,它就会发现该障碍是真的,那么该条目就是“立即选中”。这可能不太符合我们对英语单词“立即”的含义的看法,但这就是定义术语的方式。

因此,对于条件输入调用,RM 9.7.3表示如果未立即选择条目调用,则取消条目调用(并执行else分支)。使用9.5.3(8)中的定义,这意味着仅当屏障条件为假(在任务成功获取受保护对象之后)才执行else分支。

答案 1 :(得分:2)

如果Some_Entry不能立即访问,则选择'else'分支(因为已经存在另一个访问受保护对象的任务,或者因为警卫阻止了首先调用该条目。 < / p>

'else'分支的目标基本上是您的任务不会被阻止,因此可能会错过超时或定期执行的操作。因此,当你使用'else'时,select语句不能被阻塞(除非条目本身,一旦被调用,就会永远停止)。

编辑:如下面@simonwright所示,这个答案是不正确的:当guard为False时,会执行'else'分支,否则任务将阻止受保护对象的条目。按照设计,此类条目应在非常有限的时间内完成工作。