Reputation: 109
How can I shared a list of array in Perl ?
My code in sub thread:
@token_list = (@token_list, [$token, time() + 1200]);
My code in main sub:
my @array1 = [];
my @token_list : shared = ();
.
.
.
$thr = threads->new(\&connect, $c, $r);
.
.
.
foreach my $token_tab (@token_list)
{
@array1 = @$token_tab;
print "List content: $array1[0] $array1[1]\n";
}
Because soft never enter into foreach
Upvotes: 1
Views: 622
Reputation: 53478
First off - threads
are officially discouraged in perl:
The "interpreter-based threads" provided by Perl are not the fast, lightweight system for multitasking that one might expect or hope for. Threads are implemented in a way that make them easy to misuse. Few people know how to use them correctly or will be able to provide help. The use of interpreter-based threads in perl is officially discouraged.
Anyway, that aside - you talk about sharing a nested data structure. The way you're doing that doesn't work.
The problem is - the way perl handles multidimensional data structures is via references.
So with your @token_list
:
my @token_list = (@token_list, [$token, time() + 1200]);
You're actually doing:
my @token_list : shared;
my $anon_array = [ $token, time() + 1200 ];
@token_list = ( @token_list, $anon_array );
and because $anon_array
isn't shared, it doesn't work 'properly'. In order to do this, you would need to share the 'sub' array separately. share
doesn't work very well, but shared_clone
does.
use strict;
use warnings;
use threads;
use threads::shared;
use Data::Dumper;
my @array_of_arrays : shared;
for ( 0 .. 5 ) {
my $array_ref = [ 1, 2, 3, 4, 5 ];
push( @array_of_arrays, shared_clone($array_ref) );
}
print Dumper \@array_of_arrays;
sub inc_all_elements {
foreach my $outer (@array_of_arrays) {
foreach my $inner (@$outer) {
$inner++;
}
push( @$outer, 8 );
}
}
for ( 1 .. 5 ) {
threads->create( \&inc_all_elements );
}
foreach my $thr ( threads->list ) {
$thr->join;
}
print Dumper \@array_of_arrays;
This makes the inner array reference 'shared' as well as the outer, which is what's missing from your code.
I think that means it would be as simple as:
@tokens = ( @tokens, shared_clone( [$token, time() + 1200] ) );
To get your code working.
Upvotes: 1