在下面的代码中,我正在尝试创建我想在多线程中使用的正则表达式。 问题是当使用传递给线程的正则表达式时,它被编译为'Regexp = SCALAR(0x268aed0)'而不是'(?-xism:(testme))',因此正则表达式不起作用。
有谁能告诉我它为什么会这样?
我正在使用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 :(得分:0)
在调用Thread::Queue
1.46的5.18,threads::shared
3.02上运行代码,我收到'REGEXP'
不支持的引用类型的错误。一个小小的研究告诉我threads::shared
不允许共享正则表达式。正如您在此bug report中的答案中所看到的那样。
因此,您可以共享该字符串,并将其替换为已编译的 per 线程作为变通方法。看来答案是,你必须每个线程至少编译一次正则表达式,并且不能共享已编译的正则表达式。
答案 1 :(得分: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
毫不奇怪,编译的正则表达式不能在线程之间共享。看来你的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("$_");