2014-02-13 216 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的答案中看到的那樣。

因此,您可以共享字符串,並將其替換爲編譯版本,每線程作爲解決方法。看來答案是,您必須每個線程至少編譯一次正則表達式,並且不能共享編譯的正則表達式。