Выполняйте независимые задачи через concurrent и собирайте результаты в именованные поля записи. Задайте тайм-аут и укажите в else результат на случай, если время истечёт.
Установите Топаз по разделу Первая программа. Сохраните каждую программу ниже в рабочей папке и выполняйте её команды из этой папки.
Завершаем работу до тайм-аута
Сохраните код в файле concurrency-success.tpz.
let результат = concurrent(timeout: 3s) {
итого: 1 + 2
метка: "ready"
} else {
{ итого: -1, метка: "timeout" }
}
print("{результат.итого} {результат.метка}")Проверьте и запустите его.
topaz check concurrency-success.tpz
topaz run concurrency-success.tpzОбе команды завершаются с кодом 0. Когда обе задачи завершаются за три секунды, программа выводит значения полей результата.
3 readyКаждое именованное выражение внутри concurrent задаёт одну задачу, также называемую arm. Здесь итого вычисляет 3, а метка даёт "ready". Их имена становятся полями записи с результатами. Запись не показывает, какая задача началась или завершилась первой.
Возвращаем другое значение при тайм-ауте
В этой программе одна задача продолжает выполнять цикл. Сохраните код в файле concurrency-timeout.tpz.
function крутиться() -> int {
let mut счётчик = 0
while true { счётчик += 1 }
счётчик
}
let результат = concurrent(timeout: 5ms) {
зависло: крутиться()
} else {
{ зависло: -1 }
}
print("{результат.зависло}")Проверьте и запустите его.
topaz check concurrency-timeout.tpz
topaz run concurrency-timeout.tpzЧерез пять миллисекунд тайм-аут выбирает else, который задаёт весь результат. Обе команды завершаются с кодом 0.
-1При тайм-ауте результаты задач не возвращаются, даже если некоторые задачи уже завершились. Если ваша задача должна завершаться, исправьте условие цикла или входные данные. Возврат значения при тайм-ауте не исправляет незавершённую работу.
Различаем завершение, тайм-аут и ошибки выполнения
| Что произошло | Результат выражения |
|---|---|
| Все задачи завершились до тайм-аута | Запись с одним полем для каждой задачи |
| Время истекло раньше | Значение блока else |
| До тайм-аута в задаче возникла ошибка выполнения | Всё выражение завершается ошибкой, без выполнения else |
Ошибка выполнения, называемая fault, останавливает вычисление, например при выходе за границы массива. Задача, возвращающая Err(error), завершается с обычным значением Result. Это значение попадает в поле с именем задачи. Блок else обрабатывает тайм-аут, не перехватывает ошибки выполнения и не извлекает значения из Err.
Тип результата else должен быть совместим с записью успешных результатов. В обоих примерах обе ветви используют одинаковые имена полей и совместимые типы полей.
Задаём порядок вывода
Если порядок вывода важен, печатайте после возврата из concurrent. Имена задач обозначают результаты, но среда выполнения не определяет порядок запуска и завершения задач. Также не определены чередование вывода, справедливость распределения времени между задачами и повторяемость чередования от запуска к запуску.
После тайм-аута среда выполнения решает, как отменять незавершённые задачи и очищать их ресурсы. Поздние ошибки выполнения задач, результаты которых уже не ожидаются, не передаются выражению Топаза. Не полагайтесь на определённый порядок отмены или очистки.
Записываем допустимый тайм-аут
Пишите целое число и сразу за ним ms, s или m, например 5ms или 3s. Пробелы и формы свойств вроде .seconds недопустимы. Литералы длительности используются в параметре timeout выражения concurrent.
После перевода в миллисекунды значение должно помещаться в беззнаковый u64, от 0 до 18446744073709551615. Большее значение вызывает TPZ5001. Уменьшите литерал до допустимого значения.
| Единица | Наибольший допустимый литерал |
|---|---|
| Миллисекунды | 18446744073709551615ms |
| Секунды | 18446744073709551s |
| Минуты | 307445734561825m |
Давайте задачам разные имена. Тайм-аут требует else. Форма concurrent { ... } ждёт все задачи без тайм-аута и не допускает else. В примерах приложений явно задавайте тайм-аут.
В Топазе нет неявного асинхронного выполнения, async/await, доступных пользователю дескрипторов задач или общей арифметики длительностей. Об ошибках и порядке выполнения читайте в разделе Поведение среды выполнения, о неподдерживаемом синтаксисе в разделе Запрещённые и отложенные формы.