gpt4 book ai didi

perl - 从另一个递归调用一个匿名子程序是否安全?

转载 作者:行者123 更新时间:2023-12-04 18:04:40 26 4
gpt4 key购买 nike

我想使用匿名 subs 而不是命名的 subs 的原因是因为我想在 Mason subcomponents( http://www.masonbook.com/book/chapter-2.mhtml#TOC-ANCHOR-7 ) 中定义这些 subs,它们与命名的 subs 表现不佳。

例如。如果我以这种方式编写代码:

my ($first, $second);
$first = sub {
my $val = shift;
print "val: $val";
$second->($val);
};
$second = sub {
my $val = shift;
if (0 < $val) {
$val = $val - 1;
$first->($val);
}
};
$first->(10);

这种方法是否有任何隐藏的问题(例如内存泄漏等)?

正如@Schwern 所解释的那样,Perl 不会释放这些子程序的内存,因为它们之间存在循环引用。

但更具体地说,内存分配会随着 $val 的增加而线性增长,还是不依赖于调用堆栈深度?因为我可以将这些 subs 放在 mason <%once> 块中,在这种情况下,这些 subs 将只初始化一次。

最佳答案

我唯一能想到的是子程序永远不会被释放,即使 $first$second超出范围。 $first的代码是指$second , $second的代码是指$first .这是一个循环数据结构,Perl 的内存分配无法解除分配。

$ perl -wlE 'for (1..10_000) { my($first, $second); $first = sub {};  $second = sub {} } say "Done"; sleep 1000'

$ perl -wlE 'for (1..10_000) { my($first, $second); $first = sub { $second->() }; $second = sub { $first->() } } say "Done"; sleep 1000'

循环后第一个 Perl 进程使用 1912K,第二个使用 10320K。无论创建多少 CV,第一个都不会增长,第二个会。

为了解决这个问题,你必须通过取消定义 $first 来打破这个圈子。或 $second .第三个叫 undef $first在循环内部,它的内存不会增长。
$ perl -wlE 'for (1..100_000) { my($first, $second); $first = sub { $second->() }; $second = sub { $first->() }; undef $first; } say "Done"; sleep 1000'

关于perl - 从另一个递归调用一个匿名子程序是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32851481/

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