首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Perl:正确使用Storable和Thread::Queue

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

Stack Overflow用户
提问于 2013-07-17 21:36:50
回答 1查看 588关注 0票数 1

我正在尝试使用Storable来帮助收集多线程生成的数据。在没有线程部分的情况下,可存储的代码段工作得很好。然而,使用我提供的示例代码,我得到了以下错误:

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

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

@ikegami在早些时候的一篇文章中建议我这个错误是因为我引用的是一个非共享变量。我尝试与代码my %test2_hash : shared; (这是示例代码的一部分)共享该变量,但我猜我没有正确地使用它。

我还尝试创建一个新的共享散列:

代码语言:javascript
复制
my %shared_hash;
%test2_hash = %{retrieve($tmp_filename)};
%shared_hash = share(%test2_hash);

然而,这会导致相同的错误。

下面是我的示例代码:

代码语言:javascript
复制
#!/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;
}

当与Thread::Queue一起实现时,使用Storable的正确方式是什么?或者这个问题纯粹与不正确的Thread::Queue实现有关?

对不起@ikegami :(我真的试过尝试我现有的工具,但我又碰壁了。

更新:我更新了代码。使用strict和warnings,我得到以下输出:

代码语言:javascript
复制
thread failed to start: Invalid value for shared scalar at ./storable2.pl line 52.

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-18 04:23:08

因为共享结构只是为了传输它,所以可以通过序列化数据结构而不是共享它来绕过整个问题。

您可以使用Storablefreezethaw来序列化和恢复数据结构。

代码语言:javascript
复制
$queue->enqueue(freeze($_)) for @sentiments;

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

或者,您可以使用Thread::Queue::Any,这是一个类似Thread::Queue的模块,它可以自动序列化排队的项。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17701276

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档