in reply to Re^2: multithreads newbie question
in thread multithreads newbie question

Something I wasn't expecting. I'm passing one of the subroutines a hash and the subroutine does some changes in it. But those changes are not stored in the hash after the subroutines finishes!

Note that there need not be a problem of sync between the threads. They do not write to common fields. as I mentioned, I actually use this in an object so I pass $self, but this example also illustrates the problem:

##! perl -slw use 5.010; use strict; use threads; use Thread::Queue qw( ); sub sub1 { say"sub1 starts"; sleep 1 for 1..2; say"sub1 ends" } sub sub2 { my $hashref = shift; $hashref->{KEY}=1; exists($hashref->{K +EY}) ? say "KEY exists" : say "KEY does NOT exist"; say"sub2 starts"; sleep 1 for 1..2; say"sub2 ends" } sub sub3 { say"sub3 starts"; sleep 1 for 1..5; say"sub3 ends" } sub sub4 { say"sub4 starts"; sleep 1 for 1..5; say"sub4 ends" } sub sub5 { say"sub5 starts"; sleep 1 for 1..5; say"sub5 ends" } sub sub6 { say"sub6 starts"; sleep 1 for 1..5; say"sub6 ends" } sub sub7 { say"sub7 starts"; sleep 1 for 1..2; say"sub7 ends" } sub sub8 { say"sub8 starts"; sleep 1 for 1..2; say"sub8 ends" } my $hashref = {}; my $q = Thread::Queue->new(); my $t1 = async { sub1(); $q->enqueue(1); }; my $t2 = async { sub2($hashref); $q->enqueue(2); }; my $pending = 2; my @threads; for (;;) { my $id = $q->dequeue(); if ($id == 1) { $t1->join(); push @threads, async { sub3() }, async { sub4() }; --$pending; } elsif ($id == 2) { $t2->join(); exists($hashref->{KEY}) ? say "KEY exists" : say "KEY does NOT e +xist"; push @threads, async { sub5() }, async { sub6() }; --$pending; } if (!$pending) { push @threads, async { sub7() }, async { sub8() }; last; } } $_->join() for @threads;

Replies are listed 'Best First'.
Re^4: multithreads newbie question
by ikegami (Patriarch) on Aug 10, 2010 at 15:44 UTC
      thanks, I just read it, but I remained puzzled. I remind you that all these subroutines (sub_#) object's subroutines that are called from another subroutine (sub run) of the same object. So the calling subroutine gets $self and should pass $self to each of the subs. Should I share $self at the beginning of the calling subroutine (sub run)? This does not seem to make sense since the doc says that sharing deletes the content.

        You should create your variables shared. Sharing objects doesn't really make sense unless the object is specifically designed to transport data between threads. Either special purpose objects, or don't use objects at all to exchange data.