Jean
Jean

Reputation: 22705

How to share hash reference in multithread perl?

How do I share the hash reference $ref across main thread and worker threads ?

#!/usr/bin/perl
use strict;
use warnings;

use threads;
use threads::shared;

my $ref = {};
$ref->{0}->{abc} = 123;
$ref->{1}->{abc} = 223;

printf( "%d\n", $ref->{0}->{abc} );
printf( "%d\n", $ref->{1}->{abc} );

issue_all_jobs($ref);

while (1)
{
    printf( "%d\n", $ref->{0}->{abc} );
    printf( "%d\n", $ref->{1}->{abc} );
    sleep(1);
}

sub issue_all_jobs
{
    my ($ref) = @_;
    for ( my $i = 0; $i < 2; $i++ )
    {
        $ref->{$i}->{handle} = new threads( \&issue_job, $ref, $i );
        $ref->{$i}->{handle}->detach();
    }
}

sub issue_job
{
    my ( $ref, $i ) = @_;
    $ref->{$i}->{abc} = 555123 + $i;
    sleep(2);
}

Upvotes: 5

Views: 281

Answers (1)

Sobrique
Sobrique

Reputation: 53488

This doesn't work as well as you might think. One of the limitations of threads::shared is that it works fine for sharing single dimensional containers, but it gets rather messy when trying to work on nested data structures, because the compiler doesn't 'know' what it needs to share.

http://perldoc.perl.org/threads/shared.html#BUGS-AND-LIMITATIONS

So - for starters - you need to designate your shared variables as shared in the first place. Either at declaration:

my $ref : shared;

But as you're trying to share a hash

shared_clone ( $ref ); 

But personally - I'd shy away from such things. I dislike using shared memory objects, and would generally prefer to use Thread::Semaphore and Thread::Queue and pass data back and forth in a queue. Storable helps a great deal with this, as you can freeze and thaw a data object for insertion into a queue.

Upvotes: 5

Related Questions