Справочное руководство Ada 2005
9.7.4 Асинхронная передача управления
Асинхронный select_statement обеспечивает асинхронную передачу управления по завершении вызова входа или истечении задержки.
Синтаксис
Динамическая семантика
При выполнении asynchronous_select, где triggering_statement представляет собой procedure_or_entry_call, имя входа, имя процедуры или префикс процедуры, а также фактические параметры вычисляются так же, как при простом вызове входа (см. 9.5.3) или вызове процедуры (см. 6.4). Если вызов является вызовом входа или вызовом процедуры, реализованной входом, то выполняется вызов входа. Если вызов входа поставлен в очередь (или повторно поставлен в очередь с прерыванием), то выполняется abortable_part. Если вызов входа выбран немедленно и никогда не повторно поставлен в очередь с прерыванием, то abortable_part никогда не запускается. Если вызов относится к процедуре, которая не реализована входом, вызов выполняется как описано в 6.4, за которым следует sequence_of_statements альтернативы triggering_alternative; abortable_part никогда не запускается.
При выполнении asynchronous_select, где triggering_statement является delay_statement, выражение задержки expression вычисляется, и определяется время истечения, как для обычного delay_statement. Если время истечения еще не наступило, выполняется abortable_part.
Если abortable_part завершается и покидает выполнение до завершения triggering_statement, предпринимается попытка отмены triggering_statement. Если попытка отмены удается (см. 9.5.3 и 9.6), asynchronous_select завершается.
Если triggering_statement завершается не из-за отмены, то abortable_part прерывается (если начато, но еще не завершено — см. 9.8). Если triggering_statement завершается нормально, то необязательная sequence_of_statements triggering_alternative выполняется после того, как abortable_part покидает выполнение.
Примеры
Пример цикла основных команд для интерпретатора команд:
loop
select
Terminal.Wait_For_Interrupt;
Put_Line("Прервано");
then abort
-- Это будет отклонено при прерывании терминала
Put_Line("-> ");
Get_Line(Command, Last);
Process_Command(Command(1..Last));
end select;
end loop;
select
Terminal.Wait_For_Interrupt;
Put_Line("Прервано");
then abort
-- Это будет отклонено при прерывании терминала
Put_Line("-> ");
Get_Line(Command, Last);
Process_Command(Command(1..Last));
end select;
end loop;
Пример вычисления с ограничением по времени:
select
delay 5.0;
Put_Line("Вычисление не сходится");
then abort
-- Это вычисление должно завершиться за 5.0 секунд;
-- если нет, предполагается расхождение.
Horribly_Complicated_Recursive_Function(X, Y);
end select;
delay 5.0;
Put_Line("Вычисление не сходится");
then abort
-- Это вычисление должно завершиться за 5.0 секунд;
-- если нет, предполагается расхождение.
Horribly_Complicated_Recursive_Function(X, Y);
end select;