develooper Front page | perl.ithreads | Postings from March 2008

Re: Passing an IO:Handle to a Thread

Thread Previous | Thread Next
From:
Chris Hall
Date:
March 1, 2008 10:41
Subject:
Re: Passing an IO:Handle to a Thread
Message ID:
Ff3V9ehjMayHFwWH@agrotera.halldom.com
On Sat, 1 Mar 2008 you wrote
>On Sat, Mar 01, 2008 at 02:51:19PM +0000, Chris Hall wrote:
>> Whatever share $h does, it doesn't appear useful when $h is a ref to
>> something.
>>
>> Whatever my $h = &share({}) does, it's not the same as
>>          my %b : shared ; my $h = \%b ;
>>
>> Whatever &share({a => 1}) does, it doesn't return a ref to an anonymous
>> hash containing a => 1 !!

>Share is very similar to tie; when you share a container, its original
>contents become hidden/lost

OK.  I suppose I should have been able to work that out :-(

But I was still puzzled by the behaviour of:

    use warnings;
    use strict;

    use threads;
    use threads::shared;

    printf "Perl v%vd", $^V ;
    print " & threads v$threads::VERSION",
          " & threads::shared v$threads::shared::VERSION\n" ;

    sub DESTROY { my $s = shift ;
                  my $t = threads->tid() ;
                  warn "Thread #$t: DESTROY $s: ", %$s, "\n" ;
                } ;

    sub sh_hash { my %h ; return share %h ; } ;

    my %b : shared = () ;
    my %a = () ;

    my $h = \%b ;         %$h = (Test => '-$h') ;  bless $h ;
    my $g = &share({}) ;  %$g = (Test => '-$g') ;  bless $g ;
    my $f = share %a ;    %$f = (Test => '-$f') ;  bless $f ;
    my $e = sh_hash() ;   %$e = (Test => '-$e') ;  bless $e ;

    threads->new(sub {})->join;

    sleep(1) ;    # To avoid "Racing to Destruction"

where $h, $g, $f and $e appear equivalent, but don't all behave the same
way:

  Perl v5.10.0 & threads v1.67 & threads::shared v1.14
  Thread #1: DESTROY main=HASH(0x18c0d2c): Test-$g
  Thread #1: DESTROY main=HASH(0x18c0e0c): Test-$e
  Thread #0: DESTROY main=HASH(0x18878f4): Test-$e
  Thread #0: DESTROY main=HASH(0x22b08c): Test-$g
  Thread #0: DESTROY main=HASH(0x18879c4): Test-$f
  Thread #0: DESTROY main=HASH(0x1887924): Test-$h

and:

  Perl v5.8.8 & threads v1.69 & threads::shared v1.17
  Thread #1: DESTROY main=HASH(0x71e7d0): Test-$g
  Thread #1: DESTROY main=HASH(0x71e8c0): Test-$e
  Thread #0: DESTROY main=HASH(0x623810): Test-$e
  Thread #0: DESTROY main=HASH(0x6054e0): Test-$g
  Thread #0: DESTROY main=HASH(0x623870): Test-$f
  Thread #0: DESTROY main=HASH(0x623850): Test-$h

The puzzle being:

  (a) $g/$e behaves differently to $h/$f.

  (b) v5.10.0 and v5.8.8 behave the same (for the give versions of
      the modules).

However, $h and $f are references to hashes %b and %a.  %b and %a are
still in scope when thread #1 terminates -- so the reference count on
the respective hashes would not be zero, hence no DESTROY ?  Yes ?

So, what was puzzling me appears to be an artifact of the test -- it's
hard to imagine a real program where objects like $h and $f would be
created.

My apologies: after all my waffling, your original observation is the
real question...  v5.10.0 does not appear to hold off DESTROYing a
shared object until the last instance in any thread is destroyed !

Chris
-- 
Chris Hall               highwayman.com            +44 7970 277 383

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About