Курс Raku / Функційне, конкурентне, реактивне та веб-програмування / Конкурентне програмування / Потоки

Приєднання потоків

Щоб дочекатися завершення потоку, викличте на ньому .finish (пишеться також .join). Головна програма зупиняється там, аж поки потік не завершиться:

my $t = Thread.start({ say 'in the thread' });
$t.finish;
say 'done';

Це друкує:

in the thread
done

Оскільки .finish чекає, повідомлення потоку гарантовано з’явиться перед done. Без .finish порядок був би непередбачуваним, і програма могла б навіть завершитися раніше, ніж потік устигне щось надрукувати.

Коли ви запускаєте кілька потоків, ви приєднуєте кожен, щоб бути певними, що всі вони завершилися:

my $a = Thread.start({ 1 + 1 });
my $b = Thread.start({ 2 + 2 });
$a.finish;
$b.finish;
say 'both finished';

Обидва потоки працюють конкурентно, а приєднання їх обох перед останнім say гарантує, що both finished надрукується лише тоді, коли вони справді завершаться. Приєднання — це те, як ви зводите конкурентну роботу назад до передбачуваної точки у вашій програмі.

Оскільки виклик методу на з’єднанні поширюється на кожне значення, яке те містить, кілька потоків можна приєднати одним виразом. Поєднайте їх оператором all& — і викличте .finish на з’єднанні:

my $a = Thread.start({ 1 + 1 });
my $b = Thread.start({ 2 + 2 });

($a & $b).finish;
say 'both finished';

Виклик .finish на $a & $b запускає його на обох потоках, тож програма чекає, аж поки жоден із них уже не працюватиме, — той самий результат, що й приєднання їх по черзі, але читається це як «заверши обидва» і працює для будь-якої кількості потоків, поєднаних через &.

Навігація курсом

Тест — Потоки   |   Виконайте в потоці


💪 Або перейдіть одразу до вправ цього розділу.