gpt4 book ai didi

thread-safety - Lock.protect和callame

转载 作者:行者123 更新时间:2023-12-03 15:37:26 25 4
gpt4 key购买 nike

我正在尝试自动编写一个特征以对sub进行线程安全。这就是我得到的:

#| A trait to ensure that a sub is not run on multiple threads simultaneously.
multi sub trait_mod:<is> (Sub \code, :$protected!) {

# If :!protected, do nothing.
if $protected {

# Create a new lock outside the multithreaded area
my $lock = Lock.new;

# Wrap the sub with a routine that hides callsame in a lock
code.wrap: sub (|) {
$lock.protect: {callsame}
}
}
}

#| Should print "Start X and finish X" if properly protected
sub needs-protection($x) is protected {
print "Start $x and ";
sleep 1;
say "finish $x";
}

# Test it out.
# If not protected, completes in 1 second with malformed output
(1..4).hyper(:1batch, :4degree) { 
needs-protection $_
}
但是,对于AFAICT,似乎 callsame没有做任何事情(它返回 Nil就是这样)。我的猜测是,它以某种方式尝试调用 .protect的其他候选对象,但我没有看到一种方法来确保 callsame链接到包装的子对象,而不是其他方法。
我能够做到这一点
multi sub trait_mod:<is> (Sub \code, :$protected!) {
if $protected {
my $lock = Lock.new;
code.wrap: sub (|c) {
if CALLERS::<$*PROTECTED> {
$*PROTECTED = False;
return callsame;
}

$lock.protect: {
my $*PROTECTED = True;
code.CALL-ME(|c);
}
}
}
}
但这感觉很笨拙,我可能丢失了一些东西,当事情不安全时,允许 True$*PROTECTED值滑出。有没有办法在 callsame编码的块内制作直接的 protect

最佳答案

callsame这样的延迟例程会寻找最近的动态范围内的调度来恢复。传递给{callsame}方法的protect块将由protect方法调用,动态范围内最近的调度将是分配给protect的方法。因此,它将尝试遵循protect的基类中的Lock方法。没有,因此是Nil结果。
为了解决这个问题,我们需要在正确的动态范围内获取包装的目标,并使其在词法上可用。这可以使用nextcallee实现:

#| A trait to ensure that a sub is not run on multiple threads simultaneously.
multi sub trait_mod:<is> (Sub \code, :$protected!) {
# If :!protected, do nothing.
if $protected {

# Create a new lock outside the multithreaded area
my $lock = Lock.new;

# Wrap the sub with a routine that hides callsame in a lock
code.wrap: sub (|c) {
my &target = nextcallee;
$lock.protect: { target(|c) }
}
}
}

#| Should print "Start X and finish X" if properly protected
sub needs-protection($x) is protected {
print "Start $x and ";
sleep 1;
say "finish $x";
}

# Test it out.
# If not protected, completes in 1 second with malformed output
for (1..4).hyper(:1batch, :4degree) {
needs-protection $_
}
这给出了我期望的输出。

关于thread-safety - Lock.protect和callame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66295222/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com