Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);
}
like image 300
Jean Avatar asked Oct 28 '14 16:10

Jean


1 Answers

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.

like image 61
Sobrique Avatar answered Oct 16 '22 12:10

Sobrique