В Perl 5 таймауты устанавливали через сигналы (по крайней мере в моей практике, это был самый понятный способ). В Perl 6 для таймаутов можно воспользоваться промисами.
Давайте запустим бесконечный цикл и попытаемся завершить программу через две секунды.
Вот цикл. Время от времени он выводит счетчик на печать.
for 1 .. * {
.say if $_ %% 100_000;
}
Получив управление, этот цикл его никогда не отдаст. Поэтому, разумеется, таймер надо поставить до того, как мы дойдем до цикла:
Promise.in(2).then({
exit;
});
for 1 .. * {
.say if $_ %% 100_000;
}
Метод Promise.in создает промис, который будет сдержан через заданное число секунд. На этот промис мы — с помощью метода then — добавляем другой промис, который будет сразу выполнен по окончанию первого. Тело промиса — вызов exit.
Запускаем и смотрим:
$ time perl6 timeout.pl 100000 200000 300000 . . . 3700000 3800000 3900000 real 0m2.196s user 0m2.120s sys 0m0.068s
Программа успела досчитать до четырех миллионов и завершилась через две секунды.
Для сравнения — программа на Perl 5:
use v5.10;
alarm 2;
$SIG{ALRM} = sub {
exit;
};
for (my $c = 1; ; $c++) {
say $c unless $c % 1_000_000;
}
(За две секунды она успевает досчитать до 40 миллионов на том же компьютере, но это другая история.)