簡體   English   中英

Perl:如何將哈希推入子例程之外的數組中

[英]Perl: How to push a hash into an array that is outside of a subroutine

我最初嘗試通過Thread :: Queue發送哈希對象,但是根據此鏈接 ,我的Thread :: Queue和thread :: shared版本太舊了。 不幸的是,由於我要測試的系統不是我的,因此無法升級。

然后,我嘗試使用一個公共數組來存儲我的哈希。 這是到目前為止的代碼:

#!/usr/bin/perl
use strict;
use warnings;

use threads;
use Thread::Queue;
use constant NUM_WORKERS => 10;

my @out_array;
test1();

sub test1
{
    my $in_queue = Thread::Queue->new();
    foreach (1..NUM_WORKERS) {
        async {
            while (my $job = $in_queue->dequeue()) {
                test2($job);
            }
        };
    }

    my @sentiments = ("Axe Murderer", "Mauler", "Babyface", "Dragon");

    $in_queue->enqueue(@sentiments);
    $in_queue->enqueue(undef) for 1..NUM_WORKERS;
    $_->join() for threads->list();

    foreach my $element (@out_array) {
        print "element: $element\n";
    }
}

sub test2
{
    my $string = $_[0];
    my %hash = (Skeleton => $string);
    push @out_array, \%hash;
}

但是,在過程結束時, @out_array始終為空。 如果刪除腳本的線程部分,則@out_array正確填充。 我懷疑我在這里錯誤地實現了線程。

在這種情況下,我如何正確填充@out_array

您需要使其共享

 use threads::shared;
 my @out_array :shared;

我認為只要將其推入就不需要鎖定它,但是如果您這樣做了,則可以使用

 lock @out_array;

您需要共享使用thread :: shared中的工具將值推入的任何數組或哈希引用。

 push @out_array, share(%hash);

盡管如前所述,我將使用Thread :: Queue。

sub test2 {
    my ($string) = @_;
    my %hash = ( Skeleton => $string );
    return \%hash;
}

...

my $response_q = Thread::Queue->new()
my $running :shared = NUM_WORKERS;

...

    async {
        while (my $job = $request_q->dequeue()) {
            $response_q->enqueue(test2($job));
        }

        { lock $running; $response_q->enqueue(undef) if !--$running; }
    };

...

$request_q->enqueue(@sentiments);
$request_q->enqueue(undef) for 1..NUM_WORKERS;

while (my $response = $response_q->dequeue()) {
    print "Skeleton: $response->{Skeleton}\n";
}

$_->join() for threads->list();

請注意,在test2中缺少任何特定於線程的內容。 很好 您應該始終努力分離關注點。

您需要從線程return數據:

....
        async {
            my $data;
            while (my $job = $in_queue->dequeue()) {
                $data = test2($job);
            }

            return $data;
        };
...

for ( threads->list() ) {

    my $data = $_->join();
    #now you have this thread return value in $data
}

sub test2
{
    my $string = $_[0];
    my %hash = (Skeleton => $string);
    return \%hash;
}

我在這里的示例中找到了答案。

我必須更改2件事:

  • 在兩個潛艇之外共享@out_array
  • test2共享%hash
  • 增加return; test2的結尾

兩個子代碼之外的代碼:

my @out_array : shared = ();

test2子:

sub test2
{
    my $string = $_[0];
    my %hash : shared;
    $hash{Skeleton} = $string;
    push @out_array, \%hash;
    return;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM