6. Параллельные вычисления в Perl 6

Вчера мы видели, как создаются параллельные потоки с помощью слова start. Сегодня мы чуть подробнее остановимся на этом.

Вызов start создает промис, который выполняет блок кода параллельно основному потоку. После создания промиса управление тут же передается в основную программу, поэтому необходимо дождаться завершения работы треда.

my $promise = start {
    sleep 2;
    say 'Done';
}

say 'Waiting...';
await $promise;

Эта программа создает промис $promise и ждет его выполнения. На печати появляется следующее:

$ perl6 start-1.pl 
Waiting...
Done

Если убрать строку с await, то программа завершится прежде чем завершит работу блок кода из промиса, поэтому Done напечатано не будет.

Разумеется, возможно создать более одного промиса, и все они будут выполняться параллельно.

my @promises;
for 1..10 -> $n {
    push @promises, start {
        say "Done $n";
    }
}

say 'Waiting...';
await @promises;

Теперь создано десять потоков, и все они начинают работать сразу после создания. Поскольку на этот раз блок кода не содержит sleep, вывод программы может отличаться от запуска к запуску, например:

$ perl6 start-2.pl 
Done 1
Done 2
Done 3
Done 4
Done 5
Done 6
Waiting...
Done 7
Done 8
Done 9
Done 10

Вместо того, чтобы сохранять промисы в массиве (это нужно, чтобы было что передать await), удобно воспользоваться вот таким приемом с gather и take:

await gather for 1..10 -> $n {
    take start {
        say "Done $n";
    }
}

say 'Waiting...';

Еще проще конструкция с do:

await do for 1..10 -> $n {
    start {
        say "Done $n";
    }
}

say 'Waiting...';

Синтаксически, слово start — это префиксный оператор, который делает то же самое что и вызов одноименного метода класса Promise. Первую программу можно было бы переписать так:

my $promise = Promise.start({
    sleep 2;
    say 'Done';
});

say 'Waiting...';
await $promise;

Перед тем, как попрощаться сегодня, маленькое замечание: метод start применяется еще в нескольких ситуациях: при создании тредов, сапплаев и при запуске внешнего процесса. Поговорим обо всем этом в следующий раз.

5 thoughts on “6. Параллельные вычисления в Perl 6”

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *