Селекция вызова рандеву
Инструкции отбора select
могут использоваться не только для селекции принятия рандеву в задаче-сервере, но и для селекции вызова рандеву в задаче-клиенте.
В подобных случаях различные формы инструкций отбора позволяют задаче-клиенту выполнять условный вызов рандеву, временный вызов рандеву или асинхронную передачу управления.
Рассмотрим простой пример инструкции отбора для выполнения условного вызова рандеву на входе Service_1
задачи-сервера Server_Task:
select
Server_Task.Service_1 [ параметры для Service_1 ] ; else Put_Line ("Server_Task is busy!"); end select; |
В этом случае, если задача-сервер Server_Task не готова к немедленному приему рандеву на входе Service_1, то вызов рандеву будет отменен и выполнится последовательность инструкций в разделе else, которая выводит сообщение "Server_Task is busy!".
Инструкция отбора, предназначенная для условного вызова рандеву на входе задачи-сервера, как правило, используется для многократного обращения к задаче-серверу.
Таким образом, общий вид ее применения может быть следующм:
loop
select Server_Task.Service_1 [ параметры для Service_1 ] ; . . . -- опциональная последовательность инструкций, exit; -- выполняемая после рандеву else . . . -- последовательность инструкций, -- выполняемая в случае невозможности -- осуществления рандеву end select; end loop; |
Инструкция отбора для временного вызова рандеву позволяет задавать ожидание принятия рандеву на входе задачи-сервера в течение заданного интервала времени.
Пример такой инструкции для выполнения временного вызова рандеву на входе Service_1
задачи-сервера Server_Task
может иметь следующий вид:
select
Server_Task.Service_1 [ параметры для Service_1 ] ; or delay 5.0; Put_Line ("Server_Task has been busy for 5 seconds!"); end select; |
В данном случае, если в течение указанного интервала времени (здесь задан относительный интервал времени длительностью 5 секунд) задача-сервер Server_Task не приняла рандеву на входе Service_1, то вызов рандеву отменяется и выполняется последовательность инструкций, заданная альтернативой задержки, которая в этом примере выдаст сообщение "Server_Task has been busy for 5 seconds!".
Вместо относительного интервала может быть указано абсолютное значение времени:
select Server_Task.Service_1 [ параметры для Service_1 ] ; or delay until Christmas; Put_Line ("Server_Task has been busy for ages!"); end select; |
Инструкция отбора для временного вызова рандеву удобно использовать в качестве сторожевого таймера.
Таким образом, ее общий вид может быть следующм:
loop select Server_Task.Service_1 [ параметры для Service_1 ] ; . . . -- опциональная последовательность инструкций, exit; -- выполняемая после рандеву or delay интервал_времени . . . -- последовательность инструкций, -- выполняемая в случае невозможности -- осуществления рандеву end select; end loop; |
Инструкция отбора для асинхронной передачи управления (введена стандартом Ada95) позволяет задаче-клиенту продолжить выполнение какого-либо кода в то время, когда вызов рандеву ожидает обслуживания.
Пример использования такой инструкции может иметь следующий вид:
select delay 5.0; Put_Line ("Server_Task is not serviced the Service_1 yet"); then abort Server_Task.Service_1 [ параметры для Service_1 ] ; end select; |
При этом, если истечение интервала времени из инструкции delay (или delay until), расположенной после select, произойдет раньше завершения выполнения Server_Task.Service_1, то выполнение Server_Task.Service_1 принудительно прерывается и выполняется вывод сообщения "Server_Task is not serviced the Service_1 yet".
Примечательно, что использование асинхронной передачи управления не ограничено многозадачностью, например:
select delay 5.0; Put_Line ("So_Big_Calculation abandoned!"); then abort So_Big_Calculation; end select; |
При селекции вызова рандеву с помощью инструкций отбора (для осуществления условного вызова рандеву, временного вызова рандеву или асинхронной передачи управления) следует помнить, что если вызванная задача уже завершена, то выполнение инструкции отбора приведет к возбуждению исключению Tasking_Error.