raku 在具有不同参数的线程中调用相同的函数
raku Calling same function in threads with different parameters
我记得在大学时代,线程共享资源和内存。我不知道 Raku 线程实现的具体细节,但是如果多个线程同时调用具有不同参数的同一个全局函数,它们是否会相互干扰,因为全局函数是所有线程共享的单个代码块线程?例如,这个例子没有显示干扰,但是一些复杂的代码呢?
sub add ($a, $b) { $a + $b };
for 1..100 { start { sleep 1.rand; say "I am $_, {add($_, 1000)}"; } };
您不必担心同时从多个线程访问全局函数,原则上:参数按值传递,参数是函数的词法。
我能想到的是一个异常:在这样的函数中使用state
变量。状态变量的初始化存在已知的竞争条件,$foo++
形式的更新很可能在同时来自多个线程的 运行 时错过增量。例如:
my int $a;
await (^10).map: { start { $a++ for ^100000 } }
say $a; # 893127
又名,不是您期望的 1000000
。幸运的是,为了处理这种情况,我们有原子整数:
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
}
请注意,这被认为是 "plumbing",也就是仅在需要时使用它,因为它会使您陷入僵局。
我记得在大学时代,线程共享资源和内存。我不知道 Raku 线程实现的具体细节,但是如果多个线程同时调用具有不同参数的同一个全局函数,它们是否会相互干扰,因为全局函数是所有线程共享的单个代码块线程?例如,这个例子没有显示干扰,但是一些复杂的代码呢?
sub add ($a, $b) { $a + $b };
for 1..100 { start { sleep 1.rand; say "I am $_, {add($_, 1000)}"; } };
您不必担心同时从多个线程访问全局函数,原则上:参数按值传递,参数是函数的词法。
我能想到的是一个异常:在这样的函数中使用state
变量。状态变量的初始化存在已知的竞争条件,$foo++
形式的更新很可能在同时来自多个线程的 运行 时错过增量。例如:
my int $a;
await (^10).map: { start { $a++ for ^100000 } }
say $a; # 893127
又名,不是您期望的 1000000
。幸运的是,为了处理这种情况,我们有原子整数:
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
}
请注意,这被认为是 "plumbing",也就是仅在需要时使用它,因为它会使您陷入僵局。