Regex 在perl中的线程中使用编译的正则表达式

Regex 在perl中的线程中使用编译的正则表达式,regex,multithreading,perl,Regex,Multithreading,Perl,在下面的代码中,我试图创建我想在多线程中使用的正则表达式。 问题是,当使用传递到线程中的正则表达式时,它被编译为“Regexp=SCALAR(0x268aed0)”,而不是“(?-xism:(testme))”,因此正则表达式不起作用 有人能告诉我为什么会这样吗 我使用的是PerlV5.10.1 #/usr/bin/perl use threads; use Thread::Queue; my $q = Thread::Queue->new(); my @threads; for (

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

有人能告诉我为什么会这样吗

我使用的是PerlV5.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

在5.18,
Thread::Queue
3.02上运行代码,它调用
threads::shared
1.46,我得到一个错误,
'REGEXP'
是不受支持的引用类型。一些研究告诉我,
threads::shared
不允许共享regexp。正如你在这篇文章中看到的


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

运行程序时,我得到:

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
毫不奇怪,编译后的正则表达式不能在线程之间共享。您的threads::shared版本似乎没有报告此错误


最小测试用例是:

perl -Mthreads -Mthreads::shared -le'print shared_clone(qr/a/)'
使用全新的Perl 5.10.1安装,上述操作会导致以下错误输出:

Regexp=SCALAR(0xXXXXXXXX)
从不使用thread::shared的版本引发错误

Unsupported ref type: REGEXP at -e line 1

解决方法是将正则表达式的字符串化版本传递给用户

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