多线程如何共享散列数组的散列

时间:2015-01-23 15:58:14

标签: perl

我正在尝试使用线程,同时将数组分配给散列,将另一个数组分配给散列散列。

#!/usr/bin/Perl

use strict;
use threads;
use threads::shared;

my %hash :shared;
my %hash1 :shared;

my $a = "abcdef";
my $b = "ghighi";

my $len = length($a)-2;

# Define the number of threads
my $num_of_threads = 2;

# use the initThreads subroutine to create an array of threads.
my @threads = initThreads();

# Loop through the array:
foreach(@threads){
                # Tell each thread to perform our 'doOperation()' subroutine.
        $_ = threads->create(\&doOperation);
}

# This tells the main program to keep running until all threads have finished.
foreach(@threads){
    $_->join();
}

print "\nProgram Done!\nPress Enter to exit";
$a = <>;

####################### SUBROUTINES ############################
sub initThreads{
    my @initThreads;
    for(my $i = 1;$i<=$num_of_threads;$i++){
        push(@initThreads,$i);
    }
    return @initThreads;
}
sub doOperation{
    # Get the thread id. Allows each thread to be identified.
    my $id = threads->tid();
    my $i = 0;

    while($i < 2)
    {

        my $split = substr($a, $i, $len);
        my $split1 = substr($b, $i, $len);

        my $affix = substr($split, 0, $len-1);
        my $postfix = substr($split, 1, $len-1); 
        my $affix1 = substr($split1, 0, $len-1);
        my $postfix1 = substr($split1, 1, $len-1); 

    print "$affix\t$postfix\n";

        lock(%hash);
        #lock(%hash1); 

        $hash{$affix} = threads::shared::shared_clone([$affix1]);
    print "$hash{$affix}\n";
        #$hash1{$affix}{$postfix} = threads::shared::shared_clone([$affix1]); This is where the problem is. How can I assign an array to a hash of hash

        $i++
    }
    print "Thread $id done!\n";
    # Exit the thread
    threads->exit();
}

线程1异常终止:共享标量的值无效。

这是我的代码的一部分。如何在使用threads.e.g。$ hash1 {$ affix} {$ postfix} = threads :: shared :: shared_clone([$ affix1]);时将数组分配给散列哈希。这就是问题所在。如何将数组分配给散列哈希

2 个答案:

答案 0 :(得分:1)

$h{x}{y}

的缩写
$h{x}->{y}

并取消引用autovivify,所以它实际上是

( $h{x} //= {} )->{y}

现在,您想要引用共享哈希,所以

$hash1{$affix} //= &share({});
$hash1{$affix}{$postfix} = shared_clone([$affix1]);

答案 1 :(得分:1)

个人:我不会。

我不喜欢繁琐的threads::shared如何进行共享哈希的过程,所以除非绝对必要,否则要远离它。

考虑到你的代码,我建议不是 - 你最好使用Thread::Queue来整理线程的结果。 看起来就像你正在更新一个孤立的元素,而不需要再读回来。所以你可以:

use Thread::Queue;
use threads; 

my $task_q = Thread::Queue -> new(); 
my $result_q = Thread::Queue -> new(); 

sub worker { 
   while ( my $item = $task_q -> dequeue ) { 
       #extract a value to work on
       my $result = "something"; 
       $result_q -> enqueue ( $result ); 
   }
}

for ( 1..$nthreads ) {
    threads -> create ( \&worker );
}

#enqueue one or more items; 
$work_q -> enqueue ( "abcde" ); 

#close the work queue. 
$work_q -> end; 

foreach my $worker ( threads -> list() ) {
   $worker -> join;
}

$results_q -> end;

while ( my $item = $results_q -> dequeue ) {
      #process $item;
}

这意味着你根本不需要共享哈希。

另外 - 避免使用$a$b - 它们是perl中具有特殊含义的变量 - 它们由sort使用,因此它们不会在{同样的方式。