Wiggins has asked for the wisdom of the Perl Monks concerning the following question:

Objective: Build a thread shared hash of arrays.
The true application is a network port monitor.

The "key" is the connection properties, the array elements are byte counts and states and such.

Below is the minimal code for the errors. Subroutine createContract() is called once as a simple subroutine, and then started as a thread.

As is; the listed errors result.

If ':shared' is removed from %Contract, and '&share' is removed from the assignment within the sub, the code works fine (as expected).

?? So, what is the proper form for sharing a hash of arrays between threads
?? Simpler yet, how to read back what is stored, regardless of threads

#!/usr/bin/perl -w use threads; use threads::shared; use Carp; my %Contracts :shared; # hash holding allowed connections my $key; &createContract; my $monitor_thr = threads->create( \&createContract ); my $res1 = $monitor_thr->join(); #==================================================================== sub createContract { $key = "123456789"; # If you want to share a newly created reference unfortunately # you need to use "&share([])" and "&share({})" syntax due to # problems with Perl's prototyping. # man page $Contracts{$key} = &share([100,200,300,400]); printf (" %s %u^%u^%u^%u^\n", $key, $Contracts{$key}[0], $Contracts{$key}[1], $Contracts{$key}[2], $Contracts{$key}[3], ); } ----------------------- # [oldcode]# perl minThreadHash # printf (...) interpreted as function at minThreadHash line 28. # Use of uninitialized value in printf at minThreadHash line 28. # Use of uninitialized value in printf at minThreadHash line 28. # Use of uninitialized value in printf at minThreadHash line 28. # Use of uninitialized value in printf at minThreadHash line 28. # 123456789 0^0^0^0^ # Use of uninitialized value in printf at minThreadHash line 28. # Use of uninitialized value in printf at minThreadHash line 28. # Use of uninitialized value in printf at minThreadHash line 28. # Use of uninitialized value in printf at minThreadHash line 28. # 123456789 0^0^0^0^
Line # 28 is the printf(.....) line.

Replies are listed 'Best First'.
Re: Shared Hash-of-Arrays between threads?
by zentara (Cardinal) on Nov 13, 2006 at 20:20 UTC
Re: Shared Hash-of-Arrays between threads?
by liverpole (Monsignor) on Nov 13, 2006 at 19:48 UTC
    Hi Wiggins,

    Do you mean something like this? ...

    sub createContract { + $key = "123456789"; + # If you want to share a newly created reference unfortunately # you need to use "&share([])" and "&share({})" syntax due to # problems with Perl's prototyping. # man page + + $Contracts{$key} = &share([]); $Contracts{$key}[0] = 100; $Contracts{$key}[1] = 200; $Contracts{$key}[2] = 300; $Contracts{$key}[3] = 400; + printf " %s %u^%u^%u^%u^\n", $key, $Contracts{$key}->[0], $Contracts{$key}->[1], $Contracts{$key}->[2], $Contracts{$key}->[3], ; } # Generates ... 123456789 100^200^300^400^ 123456789 100^200^300^400^

    I haven't done a LOT with shared data in Perl (okay, to be honest just 1 program, where I used only shared scalars, or Thread::Queue for anything more complex), but it seems to work when you define the thing being shared first, and *then* assign to it.


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: Shared Hash-of-Arrays between threads?
by smokemachine (Hermit) on Nov 13, 2006 at 20:05 UTC
    you can use like a parameter using: threads->create(\&createContract, \%Contracts) dont using the share...
Re: Shared Hash-of-Arrays between threads?
by Anonymous Monk on Nov 15, 2006 at 13:15 UTC
    The problem is that 100,200,300 should be shared (by &share) and that doesn't work. Give empty structs to share.