2017-09-07 11 views
1

여러 항목을 선택하는 방법을 찾고 있습니다. 다음과 같은 작업을하고 블록을 선택했습니다.Ada 복수 항목 선택

only allowed alternative in timed entry call is delay 
"or" not allowed here 

기능 : 의도는이 다음과 같은 컴파일 오류가 발생,

task type t_startup_task is 
    entry start; 
    entry started; 
end t_startup_task; 

task body t_startup_task is 
    startup_sig : Boolean := False; 
begin 
    accept start; 
    busy : loop -- wait for external flag to become true 
     status.read_signal (startup_sig); 
     if startup_sig then 
     exit busy; 
     end if; 
     delay 0.1; 
    end loop busy; 
    accept started; 
end t_startup_task; 

<...> 

startup_task.start; 
select 
    startup_task.started; 
or 
    state.wait_done; -- other entry 
    abort startup_task; 
    return False; 
or 
    delay 4.0; 
end select; 

그러나 일정 시간 후 다른 곳에서 여러 (2) 작업을 실행하는 일이 완료 될 때까지 실행하거나 제한하는 것입니다 실제로 이것을하는 가장 좋은 방법은?

답변

3

불행히도 여러 항목 호출 사이를 결정할 때 select 문을 사용할 수 없습니다. 그러나이를 사용하여 항목을 수락할지 여부를 결정할 수 있으므로 세 가지 작업으로 구현해야합니다.

최종 입력 호출에서 out 매개 변수를 사용하여 반환 값을 가질 수 있습니다.

task startup_task is 
    entry start; 
    entry wait_done; 
    entry signalled; 
    entry started (success : out boolean); 
end startup_task; 

-- This task waits upon your other entry, then calls the startup_task 
-- entry once it has completed 
task startup_wait is 
    entry start; 
end startup_wait; 
task body startup_wait is 
begin 
    accept start; 
    state.wait_done; 
    startup_task.wait_done; 
end startup_wait; 

-- This task contains your busy loop and calls the startup_task 
-- entry once it has completed 
task startup_signal is 
    entry start; 
end startup_signal; 
task body startup_signal is 
begin 
    accept start; 
    busy : loop -- wait for external flag to become true 
     status.read_signal (startup_sig); 
     if startup_sig then 
      exit busy; 
     end if; 
     delay 0.1; 
    end loop busy; 
    startup_task.signalled; 
end startup_signal; 

-- This task provides the functionality of your invalid select statement, 
task body startup_task is 
    success : boolean := False; 
begin 
    -- These start signals ensure that the subtasks wait for synchronisation 
    accept start; 
    startup_wait.start; 
    startup_signal.start; 
    select 
     accept signalled; 
     abort startup_wait; 
     success := True; 
    or 
     accept wait_done; 
     abort startup_signal; 
    or 
     delay 4.0 
     abort startup_wait; 
     abort startup_signal; 
    end select; 
    accept started (success); 
end startup_task; 

<...> 

result : boolean; 
begin 
    -- this block replaces your invalid select statement 
    startup_task.start; 
    startup_task.started(result); 
    return result; 
end; 

참고로이 코드를 테스트하거나 컴파일하지는 않았지만 솔루션에 대한 아이디어를 제공해야합니다.

0

는 기술적으로, 언어는이를 허용 : 할 수

select 
    delay 4.0; 
    ... 
then abort 
    select 
     Entry1; 
     ... 
    then abort 
     Entry2; 
     ... 
    end select; 
end select; 

당신이 원하는 것을.

protected Multi_Wait is 
    procedure Task1_Ready; 
    procedure Task2_Ready; 
    entry Wait_For_Either (Task_1 : out Boolean; Task_2 : out Boolean); 
private -- Multi_Wait 
    Task1 : Boolean := False; 
    Task2 : Boolean := False; 
end Multi_Wait; 

그런 다음 코드는

select 
    Multi_Wait.Wait_For_Either (Task_1 => Task_1, Task_2 => Task_2); 

    if not Task_1 and Task_2 then 
     abort T1; 

     return False; 
    end if; 
or 
    delay 4.0; 
end select; 

귀하의 작업이 호출 할 수있는 그러나, 가장 좋은 방법은 작업이 보호 된 객체에 확인하고 PO의 항목을 기다려야 아마 2 단계 통화를 기다리는 대신 적절한 절차를 따르십시오.