В принципе вам не нужно беспокоиться о одновременном доступе к глобальной функции из нескольких потоков: аргументы передаются по значению, а параметры лексичны функции.
Существует Одно исключение , о котором я могу подумать: использование переменной state
внутри такой функции. Существует известное условие гонки при инициализации переменной состояния, и обновления в форме $foo++
, скорее всего, будут пропускать приращения при одновременном запуске из нескольких потоков. Например:
my int $a;
await (^10).map: { start { $a++ for ^100000 } }
say $a; # 893127
Ака, а не 1000000
, который вы ожидаете. К счастью, для обработки этого случая у нас есть атомы c целых чисел:
my atomicint $a;
await (^10).map: { start { $a⚛++ for ^100000 } }
say $a; # 1000000
Но это просто хвастовство, а не прямой ответ на ваш вопрос: -)
Если у вас есть фрагмент кода, который вы хотите убедиться, что одновременно выполняется только один поток, вы можете использовать Lock
и protect
метод для этого;
my $lock = Lock.new; # usually in the mainline of a program
# ... code
$lock.protect: {
# code executed by only 1 thread at a time
}
Обратите внимание, что это считается будьте "водопроводчиком", иначе используйте это только тогда, когда вам нужно, так как это открывает вам тупики.