我试图了解ADA中的R-V如何工作:
服务器(伪)代码:
task test is
entry put (num: in integer);
entry get (num: out integer);
end test;
task body test is
local_num: integer;
begin
accept put (num: in integer) do
local_num := num;
end put;
// some next processing of local_num, eg:
local_num := local_num * 2;
accept get (num: out integer) do
num := local_num;
end get;
end test;
和服务器正在进行通信的客户端如下:
client (a) | server (b)
================================
| // sleep
(call_entry) | // sleep
a.put(num) | // sleep
// sleep | (accept_entry)
// sleep | b.accept put(num)
// sleep | local_num := num;
// sleep | local_num := local_num * 2;
| ??? <--------------------- what is happening after that point?
(call_entry) | // sleep
a.get(num) | // sleep
// sleep | (accept_entry)
// sleep | b.accept get(num)
更新:(正确的流程?)
client | server (test)
================================
test.put(num) | // sleep ----------> call entry
test.get(A) | accept put(num) ----------> accept entry PUT (call entry GET to the QUEUE)
// sleep | local_num := num;
// sleep | local_num := local_num * 2;
test.get(A) | accept get(A) ----------> accept entry (removed from the QUEUE)
| // sleep
答案 0 :(得分:3)
Ada Rendez-Vous非常简单,实际上您有一个任务test
,其中有两个条目get
和put
。运行程序后,test
任务启动,因此创建local_num
值(没有定义的初始值)并执行body
但是第一个语句是{accept
1}}所以任务正在等待进入呼叫。
procedure ... is
task test is
...
end test ;
task body test is
...
end test ;
A : Integer ;
begin
-- 1. The 'test' task is started here, waiting for a call to `put`
-- 2. You call the 'put' entry, which mean that the current task (the main task)
-- is stopped until the end of the entry call.
test.put(33) ;
-- 3. Here the entry 'put' is finished, so the 2 tasks are executing
-- simultaneously
-- 4. Here we call the 'get' entry, there is a non predictive behaviour:
-- We do not know if the instruction local_num := local_num * 2; has
-- been executed or not, so 2 case:
-- - The instruction has been executed, so the 'test' task is waiting
-- and directly accept the 'get' entry, while the main task wait
-- - The instruction has not been executed, so the main 'task' wait
-- until there is someone to accept is call
-- What you're sure is that the entry 'get' won't be executed before
-- the instruction, and that someone calling 'get' will have to wait
-- until the 'test' task get to the 'accept get' instruction.
test.get(A) ;
-- 5. Here, the 'get' entry is finished, so you're sure that you have ended
-- the 'test' task
end ... ;
实际上,当您调用类似test.get
的条目时,您将松开控件,直到test.get
条目完全执行。如果没有任务等待此条目,您将等到任务请求此条目。
procedure BadTask is
-- Stupid task that will accept a 'put' entry and then a 'get' (only once)
task T is
entry get (A : out Integer);
entry put (A : in Integer);
end T ;
task body T is
LocalInteger : Integer := 0 ;
begin
accept put (A : in Integer) do
LocalInteger := A ;
end put ;
accept get (A : ouInteger) do
A := LocalInteger ;
end get ;
end T ;
A : Integer ;
begin
-- Here T is waiting for 'put'
T.get (A) ;
-- You will never get here and your program is blocked because the two tasks
-- are waiting but no one can't get the control.
end BadTask ;