在 Ada 中混合输入调用和接受 select?

Mixed entry call and accept select in Ada?

是否可以在一个 select 语句中混合使用受保护的入口调用(带屏障)和接受?不使用延迟和两个不同的连续 selects,一个用于接受,一个用于入口调用:

task body Task is
begin
  select
    accept Get;
  or
    accept Put;
  or
    Protected_Object.Alive;
  end select;
end Task;

protected body Protected_Object is
begin
  entry Alive when Is_Alive is
  ...

我希望 Task 被锁定,等待调用 Get、Put 或打开 Alive 中的屏障。

这里有几个备选方案,具体取决于您希望更频繁地发生的情况:

如果您 expect/want Get/Put 发生的次数比活着的次数多:

task body Test is
begin
    loop
        select
            accept Get;
        or
            accept Put;
        or 
            -- Pick a value that makes sense
            -- This is how long you check Get
            -- and Put before trying Alive
            delay 0.0001;  

            -- Asynchronous transfer of control
            -- will try Protected_Object.Alive
            -- until the second delay is finished
            select
                -- Pick a value that makes sense
                -- Should be much smaller than the above
                -- delay
                delay 0.0000001;  
            then abort
                Protected_Object.Alive;
            end select;

        end select;

    end loop;
end Test;

如果你 expect/want Alive 检查的次数比 Get/Put 多,那么:

task body Test is
begin
    loop
        select
            accept Get;
        or
            accept Put;
        else

            -- Asynchronous transfer of control
            -- will try Protected_Object.Alive
            -- until the delay is finished
            select
                -- Pick a value that makes sense
                delay 0.0001;  
            then abort
                Protected_Object.Alive;
            end select;

        end select;

    end loop;
end Test;

无论哪种方式,如果需要,您都需要决定 how/when 结束该循环。

请注意,您可以这样做:

select
   Protected_Object.Alive;
then abort
   select
      accept Get;
   or
      accept Put;
   end select;
end select;

这可能会给你你想要的,虽然理解 ATC 可能很棘手。