线程::队列什么都不返回 [英] Thread::queue return nothing

查看:78
本文介绍了线程::队列什么都不返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在下面的脚本中工作,在该脚本中我在@file_splitted中拆分了文件内容,并尝试应用Thread :: Queue来加快该过程.但是$result最后没有返回任何内容.您能检查一下发生了什么吗?

I working on below script in which I split file content in @file_splitted and trying to apply Thread::Queue to speed up the process. But the $result returns nothing at the end. Can you please check what happening?

my $NUM_WORKERS = 5;

my $q = Thread::Queue->new();

sub worker {
   my ($job) = @_;

   print "@_  \n################\n";
   my ($sub_name, @args) = @$job;
   my $sub_ref = \&Subroutine;
   $sub_ref->(@args);
}

{
    my $q = Thread::Queue->new();

    my @workers;

    for (1..$NUM_WORKERS) {
        push @workers, async {
            while (my $job = $q->dequeue()) {
            worker($job);
#           print "$job \n";
            }
        };
    }

    $q->enqueue($_) for @file_splitted;
    $q->end();

    for my $t(@workers){
        (my @getit)= $t->join();
        my $tmp = join '', @getit; 
        $result .= $tmp;
        print "$result\n";
    }

}

推荐答案

这是您当前的代码,但整理了一下并加了注释:

This here is your current code, but tidied up a bit, and commented:

my $NUM_WORKERS = 5;

my $q = Thread::Queue->new();

{
    # ok, so here we create a new queue for some reason that shadows the outer $q
    my $q = Thread::Queue->new();

    my @workers;
    for (1 .. $NUM_WORKERS) {
        push @workers, async {
            while (my $job = $q->dequeue()) {
                my ($sub_name, @args) = @$job; # so the $job is an arrayref
                Subroutine(@args);  # what is "Subroutine"?
            }
            # this worker does not explicitly return any values
        };
    }

    # what is @file_splitted? Does it contain arrayrefs?
    $q->enqueue($_) for @file_splitted;
    $q->end();

    for my $t (@workers){
        # where is $result declared? And why are you using a return value when you
        # don't explicitly return anything from your threads?
        $result .= join '', $t->join;
        print "$result\n";
    }

}

问题是您实际上并没有从线程中返回任何有用的信息–请注意,我删除了上面的worker子例程,因为它没有为该讨论添加任何内容,并且可能使您感到困惑.

The problem is that you aren't actually returning anything useful from your threads – note that I removed the worker subroutine above because it doesn't add anything to this discussion, and probably confused you.

很有可能,您将要创建另一个队列,线程可以从该队列中返回结果:

Quite likely, you will want to create another queue from which the threads can return results:

my $job_queue = Thread::Queue->new;
my $result_queue = Thread::Queue->new;
my @workers;
for (1 .. $NUM_WORKERS) {
    push @workers, async {
        while(defined(my $job = $job_queue->dequeue)) {
            my $result = Subroutine($job);  # or something like this
            $result_queue->enqueue($result);
        }
        $result_queue->enqueue(undef);
    };
}

$job_queue->enqueue(@jobs);
$job_queue->end;

my $waiting = $NUM_WORKERS;
my @results;
while ($waiting) {
    if (defined(my $result = $result_queue->dequeue)) {
        # do something with the results
        push @results, $result;
    }
    else {
        $waiting--;
    }
}

$_->join for @workers;

如果只想最后收集所有结果,则可以执行以下操作:

If you only want to collect all results at the end, you could do something like this instead:

my $job_queue = Thread::Queue->new;
my $result_queue = Thread::Queue->new;
my @workers;
for (1 .. $NUM_WORKERS) {
    push @workers, async {
        while(defined(my $job = $job_queue->dequeue)) {
            my $result = Subroutine($job);  # or something like this
            $result_queue->enqueue($result);
        }
    };
}

$job_queue->enqueue(@jobs);
$job_queue->end;

$_->join for @workers;

my @results = $result_queue->dequeue($result_queue->pending);

这篇关于线程::队列什么都不返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆