2014-02-13 203 views
0

在下面的代码中,我试图创建我想在多线程中使用的正则表达式。 问题是,当使用传递到线程中的正则表达式时,它被编译为'Regexp = SCALAR(0x268aed0)'而不是'(?-xism:(testme))',因此正则表达式不起作用。在perl中使用编译正则表达式在线程中

谁能告诉我为什么这样做?

我使用的是perl v5.10.1。

#/usr/bin/perl 

use threads; 
use Thread::Queue; 

my $q = Thread::Queue->new(); 

my @threads; 
for (1..2) { 
    push @threads, async { 
     while (defined(my $source = $q->dequeue())) { 
      my $text = "I want you to testme 
      andmetoo please"; 
      my $re = $source->{regex}; 

      print "testing regex: " . $re . " for source $source->{id}\n"; 
      if ($text =~ $re) { 
       print "GOT IT: " . $1 . "\n"; 
      } 
     } 
    } 
} 

my @sources = (
    { 
     regex => qr/(testme)/, 
     id => 's1' 
    }, 
    { 
     regex => qr/(andmetoo)/, 
     id => 's2' 
    } 
); 

for (@sources) { 
    print "adding source with regex $_->{regex} for source $_->{id}\n"; 
    $q->enqueue($_); 
} 

$q->enqueue(undef) for @threads; 
$_->join() for @threads; 

的代码的输出上面:

adding source with regex (?-xism:(testme)) for source s1 
adding source with regex (?-xism:(andmetoo)) for source s2 
testing regex: Regexp=SCALAR(0x268aed0) for source s1 
testing regex: Regexp=SCALAR(0x268aee8) for source s2 

回答

0

运行您的程序,我得到:

adding source with regex (?^:(testme)) for source s1 
Unsupported ref type: REGEXP at a.pl line 37. 
Perl exited with active threads: 
     2 running and unjoined 
     0 finished and unjoined 
     0 running and detached 

毫不奇怪,编译正则表达式不能线程之间共享。看来你的线程版本::共享没有报告这个错误。


最小测试用例是:

perl -Mthreads -Mthreads::shared -le'print shared_clone(qr/a/)' 

使用新鲜的Perl 5.10.1安装后,上述结果在下面的不正确的输出:

Regexp=SCALAR(0xXXXXXXXX) 

决不版本螺纹::共享抛出一个错误。

Unsupported ref type: REGEXP at -e line 1 

的解决方法是通过跨越正则表达式的字符串化版本。

$q->enqueue("$_"); 
+0

谢谢,这帮了我很多! – sva

0

运行你的代码5.18,Thread::Queue 3.02,这就要求在threads::shared 1.46,我得到一个错误,'REGEXP'是不受支持的引用类型。有一项研究告诉我threads::shared不允许共享正则表达式。正如你可以从这个bug report的答案中看到的那样。

因此,您可以共享字符串,并将其替换为编译版本,每线程作为解决方法。看来答案是,您必须每个线程至少编译一次正则表达式,并且不能共享编译的正则表达式。