duelafn has asked for the wisdom of the Perl Monks concerning the following question:
I was trying to do some threaded computations and ran into a problem (keys in my shared hash become mysteriously undefined) when one of the subroutines that I called localized $_. If I change the subroutine to use a my variable, everything works fine. I was wondering whether this sort of behavior should have been expected or not.
Here is the simplified code that I'm using. The only interesting thing that happens is in the second to last line of code where I set $$x{foo}. If I use doit_local then $$x{path} becomes an undefined value, however if I use doit_my, $$x{path} retains its proper value.
#!/usr/bin/perl use 5.008; use strict; use warnings; use threads; use threads::shared; use Data::Dumper; my %p1 :shared; my %p2 :shared; %p1 = (path => shift); %p2 = (path => shift); my @t; push @t, threads->create(\&get_md5sums, \%p1); push @t, threads->create(\&get_md5sums, \%p2); $t[0]->join; $t[1]->join; print Dumper \%p1, \%p2; sub doit_local { local $_ = shift; s/'/'\''/g; return $_; } sub doit_my { my $x = shift; $x =~ s/'/'\''/g; return $x; } sub get_md5sums { my $x = shift; print Dumper [$x, $$x{path}]; $$x{foo} = join " ", map '"'.doit_local($_).'"', 'find', $$x{path}, +qw/-type f -exec md5sum {} ;/; return 1; }
Here is the output when I use doit_my. This is the desired output
[duelafn@jhegaala tmp]$ ./local_threads foo bar $VAR1 = [ { 'path' => 'foo' }, 'foo' ]; $VAR1 = [ { 'path' => 'bar' }, 'bar' ]; $VAR1 = { 'path' => 'foo', 'foo' => '"find" "foo" "-type" "f" "-exec" "md5sum" "{}" ";" +' }; $VAR2 = { 'path' => 'bar', 'foo' => '"find" "bar" "-type" "f" "-exec" "md5sum" "{}" ";" +' };
And this is what I get when I use doit_local. Before localizing $_ the shared hash has its correct values, however afterward, the path key is undefined.
[duelafn@jhegaala tmp]$ ./local_threads foo bar $VAR1 = [ { 'path' => 'foo' }, 'foo' ]; Use of uninitialized value in substitution (s///) at ./local_threads l +ine 25. Use of uninitialized value in concatenation (.) or string at ./local_t +hreads line 38. $VAR1 = [ { 'path' => 'bar' }, 'bar' ]; Use of uninitialized value in substitution (s///) at ./local_threads l +ine 25. Use of uninitialized value in concatenation (.) or string at ./local_t +hreads line 38. $VAR1 = { 'path' => undef, 'foo' => '"find" "" "-type" "f" "-exec" "md5sum" "{}" ";"' }; $VAR2 = { 'path' => undef, 'foo' => '"find" "" "-type" "f" "-exec" "md5sum" "{}" ";"' };
My perl version:
[duelafn@jhegaala tmp]$ perl --version This is perl, v5.8.4 built for i386-linux-thread-multi
Good Day,
Dean
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Problem localizing $_ using threads::shared
by dave_the_m (Monsignor) on Nov 13, 2005 at 01:12 UTC | |
by duelafn (Parson) on Nov 13, 2005 at 13:21 UTC | |
|
Re: Problem localizing $_ using threads::shared
by BrowserUk (Patriarch) on Nov 12, 2005 at 22:48 UTC | |
by duelafn (Parson) on Nov 13, 2005 at 13:08 UTC |