use Devel::Pointer; ... my $obj = deref ( $addr ) ; my $root = shift ( @{$obj->{dirToFetch}} ) ; #### ... sub _walk { my $obj = shift; my $root = shift ( @{$obj->{dirToFetch}} ) ; $obj -> _fetchDir ( $root ) ; } ... threads->create ( '_walk' , $self ) -> join; #### ... push my @running, threads->create ( '_walk' , $self ); ... while( @running ) { my $next = shift @running; $next->join; }; #### #! perl -slw use strict; use threads; use Thread::Queue; my $directories = Thread::Queue->new(); my $files = Thread::Queue->new(); use vars '$NUM_CPUS'; $NUM_CPUS ||= 4; sub _walk { while( defined my $dir = $directories->dequeue) {; my @entries = ...; for my $e (@entries) { if( -d $e ) { # depth-first search $directories->insert(0, $e); } else { # It would be much faster to enqueue all files in bulk instead # of enqueueing them one by one, but first get it working before # you make it fast $files->enqueue( $e ); }; }; }; } $directories->enqueue( @ARGV ); for ( 1..$NUM_CPUS ) { threads->new( \&_walk )->detach; }; print while defined( $_ = $files->dequeue ); print 'Done';