В 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 миллионов на том же компьютере, но это другая история.)