具有子例程的线程不返回任何内容

时间:2014-01-10 12:01:35

标签: regex multithreading perl

我是线程的新手。我编写了一个脚本来检查线程模块,其中我有一些模块,它们做一些模式匹配作业并返回两个值,第一个输入和第二个匹配找到实例及其行号。但是使用线程它什么都不返回。 这是代码

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;

}

有人能告诉我代码中有什么问题吗?

1 个答案:

答案 0 :(得分:3)

啊,是的,一个常见问题:传递给threads->create的代码引用是在调用create方法的上下文中调用的。在这里,这是标量上下文。因此return $filebuf, $found相当于return $found

当您在加入线程时在列表上下文中使用该单个元素时,您执行的操作等同于$filebuf = $t->join, $tmp = undef,这与您期望的不同。

这可以通过两种方式解决:

  1. 在列表上下文中创建线程:

    my ($thr1) = threads->create(...)
    
  2. 明确指定上下文:

    my $thr1 = threads->create({context => 'list'}, \&sub_pattern1, $filebuf);
    
  3. 另请参阅threads documentation中的上下文部分。

    另请注意,没有理由返回$filebuf,因为您没有真正使用该值 - 您只需返回已加入的最后一个帖子的$filebuf

    提示:如果您正在使用多线程来提高性能,那么您应该使用和不使用线程对代码进行基准测试 - 在您的情况下,非线程(顺序)解决方案可能会表现得更好。