在 Perl 中使用多线程时,应该如何更新哈希值的哈希值?

发布于 2024-09-19 18:31:12 字数 2264 浏览 6 评论 0原文

过去几个小时我一直在试图解决这个问题,现在我真的很困惑。

这就是我的任务概要。我应该编写一个 Perl 子例程来获取对哈希值的哈希值的引用。

我有另一个子(helper),它获取单个内部哈希并执行一些操作,包括添加键。

sub helper {
    $href = shift;
    $href->{NEW_KEY}=1;
}

由于每个内部哈希值都是独立的,因此我想使用多线程来调用helper

我正在使用 Thread::Pool::Simple几乎没有任何文档。我的 Perl 版本不支持 Thread::Pool

所以我有这样的事情:

sub my_sub {
    $hohref = shift;

    # create thread pool
    my $pool = Thread::Pool::Simple->new(
        do  => [ \&helper ]
    );

    # submit jobs
    foreach my $hashref ( values %{$hohref} ) {
        $pool->add( $hashref );
    }

    # wait for all threads to end
    $pool->join();
}

关键点是我希望散列的主散列能够反映对内部散列所做的所有更改。

my_sub 获取对 $hohref 的非共享引用,因此我尝试在 my_sub 主体中创建共享副本:

my $shared_hohref = shared_clone $hohref;

使用它并返回它,但是尽管如此,内部哈希值仍然没有更新。

当我使用完全相同的代码,但只需用一个简单的循环替换所有线程池块

foreach my $hashref ( values %{$hohref} ) {
    helper( $hashref );
}

时,一切都会正常工作。

我们将非常感谢您的帮助。

更新

请参阅这个可运行的示例:

use strict;
use warnings;

use threads;
use threads::shared;

use Thread::Pool::Simple;
use 5.010;

use Data::Dumper;

sub helper {
    say "helper starts";
    my $href  = shift;
    say "href is $href";
    $href->{NEW_KEY} = 1;
    say "helper ends with $href";
}


sub my_sub {
    my $hohref = shift;

    my $shared_hohref = shared_clone $hohref;
    my $pool = Thread::Pool::Simple->new( do => [\&helper] );

    # submit jobs
    foreach my $hashref ( values %{$shared_hohref} ) {
        say "adding to pool: $hashref";
        $pool->add($hashref);
    }

    # wait for all threads to end
    $pool->join();

    return $shared_hohref;
}

my $hoh = {
    A => { NAME => "a" },
    B => { NAME => "bb" }
};

say "1\t", Dumper $hoh;
my $updated_hoh = my_sub($hoh);
say "2\t", Dumper $updated_hoh;

“helperstarts”但就是这样......它发生了什么?

I have been spending the last hours trying to figure this out and now I'm really confused.

This is the outline of my task. I should write a Perl subroutine that gets a reference to a hash of hashes.

I have another sub (helper) that gets a single inner hash and does some stuff to with, including adding keys.

sub helper {
    $href = shift;
    $href->{NEW_KEY}=1;
}

Since each of the internal hashes is independent of the others, I would like to use multi-threading to call helper.

I'm using Thread::Pool::Simple which almost lacks any documentation. Thread::Pool is not supported by my Perl version.

So I have something like this:

sub my_sub {
    $hohref = shift;

    # create thread pool
    my $pool = Thread::Pool::Simple->new(
        do  => [ \&helper ]
    );

    # submit jobs
    foreach my $hashref ( values %{$hohref} ) {
        $pool->add( $hashref );
    }

    # wait for all threads to end
    $pool->join();
}

The key point is that I would like the main hash of hashes to reflect all the changes made to the inner hashes.

my_sub gets an unshared reference to $hohref so I tried creating a shared copy in the body of my_sub:

my $shared_hohref = shared_clone $hohref;

use it and return it instead, but still, the internal hashes were not updated.

When I use the exact same code, but simply replace all the thread pool block with a simple loop

foreach my $hashref ( values %{$hohref} ) {
    helper( $hashref );
}

then everything works fine.

Your help would be greatly appreciated.

UPDATE

See this runnable example:

use strict;
use warnings;

use threads;
use threads::shared;

use Thread::Pool::Simple;
use 5.010;

use Data::Dumper;

sub helper {
    say "helper starts";
    my $href  = shift;
    say "href is $href";
    $href->{NEW_KEY} = 1;
    say "helper ends with $href";
}


sub my_sub {
    my $hohref = shift;

    my $shared_hohref = shared_clone $hohref;
    my $pool = Thread::Pool::Simple->new( do => [\&helper] );

    # submit jobs
    foreach my $hashref ( values %{$shared_hohref} ) {
        say "adding to pool: $hashref";
        $pool->add($hashref);
    }

    # wait for all threads to end
    $pool->join();

    return $shared_hohref;
}

my $hoh = {
    A => { NAME => "a" },
    B => { NAME => "bb" }
};

say "1\t", Dumper $hoh;
my $updated_hoh = my_sub($hoh);
say "2\t", Dumper $updated_hoh;

'helper starts' but that's it... what ever happens to it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文