Курс языка программирования 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 выполняет его
для обоих потоков, поэтому программа ждёт, пока не останется ни одного
работающего, — тот же результат, что и при поочерёдном присоединении, но
читается это как «заверши оба» и работает для любого числа потоков,
объединённых через &.
Навигация по курсу
← Тест — Потоки | Выполните в потоке →
💪 Или перейдите сразу к упражнениям этого
раздела.