Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading Perl:在线程中使用eval时为空变量_Multithreading_Perl_Eval - Fatal编程技术网

Multithreading Perl:在线程中使用eval时为空变量

Multithreading Perl:在线程中使用eval时为空变量,multithreading,perl,eval,Multithreading,Perl,Eval,将项目从perl 5.8.8更新到perl 5.18.2时,我遇到了一个问题。 我已将问题简化为以下示例: use threads; my $key = "abcdef"; print "test1 key = $key.\n"; my $thr = threads->create(sub { eval "print \"test2 key = \$key.\n\";"; }); $thr->join(); 在perl 5.8.8中,这提供了正确的输出: test

将项目从perl 5.8.8更新到perl 5.18.2时,我遇到了一个问题。
我已将问题简化为以下示例:

use threads;

my $key = "abcdef";

print "test1 key = $key.\n";

my $thr = threads->create(sub {
    eval "print \"test2 key = \$key.\n\";";
}); 

$thr->join();
在perl 5.8.8中,这提供了正确的输出:

test1 key = abcdef.
test2 key = abcdef.
但在perl 5.18.2中,我有:

test1 key = abcdef.
test2 key = .
我尝试过其他perl版本,问题似乎出现在5.14.0版本中。 我正在寻找纠正这个问题的最佳方法,以及关于perl beaviour修改的解释

我已经找到了一些替代方案,但没有一个适合我:

  • 使用“我们的$key”而不是“我的$key”;但这使得变量“更公开”
  • 在评估行之前添加“my$toto=$key;”(在评估行中仍然使用$key);事实上,在eval行之前使用$key做一些事情(打印、做作、使用…)似乎可以解决问题。但是添加的行对于函数是无用的

在eval命令中使用$key而不是\$key对我来说不是一个解决方案,因为在实际的程序中,我将处理更复杂的结构。

这个问题与线程无关。看到一条类似的线。要创建闭包,编译器需要知道将使用的变量。您可以在要关闭的子项中提及变量:

my $thr = threads->create(sub {
    $key;  # Create a closure.
    eval "print \"test2 key = \$key.\n\";";
}); 
要查看类似的非线程情况,只需创建一个作用域:

my $sub = do {
    my $key = "abcdef";
    print "test1 key = $key.\n";
    sub {
        $key; # <-- Comment this line to get no value.
        eval "print \"test2 key = \$key.\n\";";
    }
};

$sub->();
my$sub=do{
my$key=“abcdef”;
打印“test1 key=$key.\n”;
潜艇{
$key;#();

Perl有两个名为
eval
的函数

  • eval EXPR
    解析并执行Perl代码

  • eval BLOCK
    是一个异常陷阱。这在其他语言中通常称为
    try


使用适当的函数将解决您的问题,因为它不会尝试使用不再存在的变量。

谢谢您的回答!您知道为什么它在使用perl 5.8.8时没有添加对变量的提及吗?您想知道为什么5.8.8捕获了它不需要的变量?因为它就是这样编码的。@ikegami:听起来不错熟悉:)这是包括我在内的许多人发现的一个bug,最终在5.14中得到了修复。它导致闭包捕获了太多的外部范围,这有时会对引用计数和内存回收造成不良后果。