我是线程的新手。我编写了一个脚本来检查线程模块,其中我有一些模块,它们做一些模式匹配作业并返回两个值,第一个输入和第二个匹配找到实例及其行号。但是使用线程它什么都不返回。 这是代码
use threads;
sub pattern_finder($){
my $filebuf = shift;
my @threads;
my $pattern_found;
my $thr1 = threads->create(\&sub_pattern1,$filebuf);
push(@threads, $thr1);
my $thr2 = threads->create(\&sub_pattern2,$filebuf);
push(@threads, $thr2);
my $thr3 = threads->create(\&sub_pattern3,$filebuf);
push(@threads, $thr3);
for my $t(@threads){
($filebuf, $tmp)= $t->join();
$pattern_found .= $tmp;
}
return $filebuf, $pattern_found;
}
sub sub_pattern1($)
{
my ($filebuf) = shift;
my $found;
while($filebuf =~ /<LINE(\d+)>Pattern1/gsi)
{
$found .= "Pattern1 found at line $1\n";
}
return $filebuf, $found;
}
sub sub_pattern2($)
{
my ($filebuf) = shift;
my $found;
while($filebuf =~ /<LINE(\d+)>Pattern2/gsi)
{
$found .= "Pattern2 found at line $1\n";
}
return $filebuf, $found;
}
sub sub_pattern3($)
{
my ($filebuf) = shift;
my $found;
while($filebuf =~ /<LINE(\d+)>Pattern3/gsi)
{
$found .= "Pattern3 found at line $1\n";
}
$found = "$pre_checks"."$found";
return $filebuf, $found;
}
有人能告诉我代码中有什么问题吗?
答案 0 :(得分:3)
啊,是的,一个常见问题:传递给threads->create
的代码引用是在调用create
方法的上下文中调用的。在这里,这是标量上下文。因此return $filebuf, $found
相当于return $found
。
当您在加入线程时在列表上下文中使用该单个元素时,您执行的操作等同于$filebuf = $t->join, $tmp = undef
,这与您期望的不同。
这可以通过两种方式解决:
在列表上下文中创建线程:
my ($thr1) = threads->create(...)
明确指定上下文:
my $thr1 = threads->create({context => 'list'}, \&sub_pattern1, $filebuf);
另请参阅threads
documentation中的上下文部分。
另请注意,没有理由返回$filebuf
,因为您没有真正使用该值 - 您只需返回已加入的最后一个帖子的$filebuf
。
提示:如果您正在使用多线程来提高性能,那么您应该使用和不使用线程对代码进行基准测试 - 在您的情况下,非线程(顺序)解决方案可能会表现得更好。