【发布时间】:2013-08-28 17:41:51
【问题描述】:
在下面的片段中,如何区分我的子 foo 的第二个调用实例和第一个?
while ($whatever) {
foo(); foo(); # foo() and foo() have the same caller package, file, and line
}
返回 file、line 和 column 之类的 super-caller() 就可以解决问题。我不想使用源过滤器。
背景,或者,这不是一个 XY 问题吗?
我有一个便利模块,Local::Thread::Once,它以面向对象的方式以及作为子例程属性公开像 pthread_once/std::call_once 这样的功能。这些都很容易,因为在任何一种情况下都有一个自然且明确的“once_control”或“once_flag”。
但是,还有一个过程接口 — once { ... } — 目前基于 caller 返回的 $filename 和 $line 进行序列化。像这样的:
sub once(&) {
my $user_routine = shift;
my (undef, $file, $line) = caller;
my $once_control = get_a_shared_flag_just_for_this_invocation($file, $line);
lock($once_control);
if (! $once_control) { $once_control++; $user_routine->(); }
return;
}
这并不完全是它的工作方式——真正的效率更高——但重点是调用与调用者的文件和行无关。这可行,只是它无法区分同一行上的两个调用。
while ($whatever) {
once { foo(); }
once { bar(); } # OK, foo() and bar() each called only once
once { baz(); }; once { buz(); }; # :( buz() not called, not even once
}
请注意,$user_routine 的地址不能用作附加判别式,因为 subs 是从一个 ithread 复制到另一个。
我可以忍受这个问题作为一个非常人为的用例的记录限制,但我更愿意以某种方式解决它。
【问题讨论】:
标签: multithreading perl