use strict ; use warnings ; use MCE::Hobo ; use MCE::Shared ; use Data::Dumper ; sub task1 { print "Starting task 1 for $_[0]\n" ; sleep 2 ; print "Finished task 1 for $_[0]\n" ; } sub task2 { print "Starting task 2 for $_[0]\n" ; sleep 4 ; print "Finished task 2 for $_[0]\n" ; } sub task3 { print "Starting task 3 for $_[0]\n" ; sleep 6 ; print "Finished task 3 for $_[0]\n" ; } MCE::Hobo->init( max_workers => 2, # hobo_timeout => 10, # posix_exit => 1, ) ; my $mutex = MCE::Mutex->new ; # Construct the shared hash first before assigning key-value pairs. tie my %test, 'MCE::Shared' ; # Internally, STORE deeply-shares array/hash references automatically. %test = ( L1_counter1 => 1, # L1_counter2 => 2, # L1_counter3 => 3, nested1 => { L2_counter1 => 3, # L2_counter2 => 2, # L2_counter3 => 1, }, ) ; sub executeTasks { my $in = $_[0] ; foreach( sort keys %{ $in } ) { my $ref = ref( my $val = $in->{ $_ } ) ; if ( $ref && $val->blessed eq 'MCE::Shared::Hash' ) { executeTasks( $val ) ; } else { if ( $val == 1 ) { mce_async { task1( $_ ) ; $mutex->enter(sub { ++$in->{ $_ } ; }) ; } ; } elsif ( $val == 2 ) { mce_async { task2( $_ ) ; $mutex->enter(sub { ++$in->{ $_ } ; }) ; } ; } elsif ( $val == 3 ) { mce_async { task3( $_ ) ; $mutex->enter(sub { ++$in->{ $_ } ; }) ; } ; } ; } ; } ; } ; # Dump shared hash. print Dumper( tied( %test )->export( { unbless => 1 } ) ) ; # Begin processing. executeTasks( \%test ) ; # Reap any remaining Hobo workers. MCE::Hobo reaps workers # automatically to not exceed max_workers when given. MCE::Hobo->waitall ; # Dump shared hash. print "\n", Dumper( tied( %test )->export( { unbless => 1 } ) ) ;