简体   繁体   English

Perl:正确使用Storable和Thread :: Queue

[英]Perl: Using Storable and Thread::Queue correctly

I'm trying to use Storable to help gather the data generated by multiple threads. 我正在尝试使用Storable帮助收集多个线程生成的数据。 Without the threading parts, the Storable bits of code work well. 如果没有线程部分,则代码的可存储位可以正常工作。 However, with the example code I provided, I get the following error: 但是,使用我提供的示例代码,出现以下错误:

thread failed to start: Invalid value for shared scalar at ./storable2.pl line 55.

Line 55 is $hash{"Simpsons"}{"Krusty"} = \\%test2_hash; 第55行是$hash{"Simpsons"}{"Krusty"} = \\%test2_hash;

@ikegami had advised me in an earlier post that the error is caused because my reference is ponting to an unshared variable. @ikegami在较早的帖子中告诉我,该错误是由于我的引用响应了一个未共享的变量而引起的。 I tried sharing the variable with the code my %test2_hash : shared; 我尝试与my %test2_hash : shared;的代码共享变量my %test2_hash : shared; (which is part of the example code) but I guess I'm using it incorrectly. (这是示例代码的一部分),但我想我使用的方式不正确。

I also tried creating a new hash that was shared: 我还尝试创建一个共享的新哈希:

my %shared_hash;
%test2_hash = %{retrieve($tmp_filename)};
%shared_hash = share(%test2_hash);

However that results in the same error. 但是,这将导致相同的错误。

Here is my example code: 这是我的示例代码:

#!/usr/bin/perl
# storable.pl

use strict;
use warnings;
use Storable qw(store retrieve);
use File::Temp;
use threads;
use threads::shared;
use Thread::Queue;
use constant NUM_WORKERS => 10;
use Data::Dumper qw(Dumper);

my @out_array;

main();

sub main
{
    start_threads();
    foreach my $item (@out_array) {
        print "item: $item\n";
    }
}

sub start_threads
{
    my $queue = Thread::Queue->new();
    foreach (1..NUM_WORKERS) {
        async {
            while (my $job = $queue->dequeue()) {
                test1($job);
            }
        };
    }
    my @sentiments = ("Axe Murderer", "Mauler", "Babyface", "Dragon");
    $queue->enqueue(@sentiments);
    $queue->enqueue(undef) for 1..NUM_WORKERS;
    $_->join() for threads->list();

    my @return_array = @out_array;
    return @return_array;   
}

sub test1
{
    my $fighter = $_[0];
    my $tmp_filename : shared;
    my %hash : shared;
    my %test2_hash : shared;
    $tmp_filename = get_temp_filename();
    test2($fighter, $tmp_filename);
    %test2_hash = %{retrieve($tmp_filename)};

    $hash{"Simpsons"}{"Krusty"} = \%test2_hash;
    push @out_array, \%test2_hash;
    return;
}

sub test2
{
    my ($fighter, $tmp_filename) = @_;
    my %test2_hash;
    $test2_hash{"Zuffa"}{"LLC"} = $fighter;
    store(\%test2_hash, $tmp_filename);
}

sub get_temp_filename {
    my $fh = File::Temp->new(
        TEMPLATE => 'tempXXXXX',
        DIR      => 'tmpdir',
        SUFFIX   => '.tmp',
    );
    return $fh->filename;
}

What is the correct way to use Storable when implemented alongside Thread::Queue? 与Thread :: Queue一起实现时,使用Storable的正确方法是什么? Or is the problem purely related to incorrect Thread::Queue implementation? 还是问题纯粹与不正确的Thread :: Queue实现有关?

Sorry @ikegami :( I really tried to experiment around with the tools I have, but I've hit a wall again. 抱歉@ikegami :(我真的很想尝试使用我拥有的工具,但是我又碰壁了。

UPDATE: I updated the code. 更新:我更新了代码。 Using strict and warnings I get the following output: 使用严格和警告,我得到以下输出:

thread failed to start: Invalid value for shared scalar at ./storable2.pl line 52.

Line 52 is %test2_hash = %{retrieve($tmp_filename)}; 第52行是%test2_hash = %{retrieve($tmp_filename)};

Since you're only sharing the structure in order to transmit it, you could bypass the entire issue by serializing your data structure instead of sharing it. 由于您仅共享结构以进行传输,因此可以通过序列化数据结构而不是共享结构来绕过整个问题。

You could use Storable 's freeze and thaw to serialize and restore your data structure. 您可以使用Storablefreezethaw来序列化和还原您的数据结构。

$queue->enqueue(freeze($_)) for @sentiments;

while (my $job = $queue->dequeue()) {
    test1(thaw($job));
}

Alternatively, you could use Thread::Queue::Any , a module like Thread::Queue which serializes queued items automatically. 另外,您可以使用Thread :: Queue :: Any ,如Thread :: Queue这样的模块,该模块可以自动序列化排队的项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM