在 Perl 中使用多线程时,应该如何更新哈希值的哈希值?
过去几个小时我一直在试图解决这个问题,现在我真的很困惑。
这就是我的任务概要。我应该编写一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
请参阅 http://www.perlmonks.org/?node_id=860786。
See http://www.perlmonks.org/?node_id=860786.