use strict;
use warnings;
package Foo {
use MCE::Shared ;
sub new {
my $class = shift ;
my $this = { } ;
tie my %data, 'MCE::Shared', _var => 1 ;
$this->{ _SHARED_DATA } = \%data ;
$this->{ _MUTEX } = MCE::Mutex->new ;
bless $this, $class ;
}
sub task {
# Long operation task Foo ~ 2 seconds
my $this = shift ;
print "Starting task Foo for $_[0]\n" ;
sleep 2 ;
$this->{ _MUTEX }->enter( sub {
++$this->{ _SHARED_DATA }{ _var } ;
}) ;
print "Finished task Foo for $_[0]\n" ;
}
sub export {
my $this = shift ;
my %clone = %{ $this } ;
delete $clone{ _MUTEX } ;
return \%clone ;
}
} ;
package Bar {
use MCE::Shared ;
use Scalar::Util 'blessed' ;
sub new {
my $class = shift ;
# This is not very realistic code.
# here it is just used as an
# example to create an object that
# contains a nested object
my $this = { nestedFoo => $_[0] } ;
tie my %data, 'MCE::Shared', _var => 1 ;
$this->{ _SHARED_DATA } = \%data ;
$this->{ _MUTEX } = MCE::Mutex->new ;
bless $this, $class ;
}
sub task {
my $this = shift ;
if ( @_ == 2 ) {
$this->{ $_[0] }->task( $_[1] ) ;
return ;
}
# Long operation task Bar ~ 6 seconds
print "Starting task Bar for $_[0]\n" ;
sleep 6 ;
$this->{ _MUTEX }->enter( sub {
++$this->{ _SHARED_DATA }{ _var } ;
}) ;
print "Finished task Bar for $_[0]\n" ;
}
sub export {
my $this = shift ;
my %clone = %{ $this } ;
delete $clone{ _MUTEX } ;
for ( keys %clone ) {
next unless blessed( $clone{ $_ } ) ;
next unless $clone{ $_ }->can('export') ;
$clone{ $_ } = $clone{ $_ }->export ;
}
return \%clone ;
}
} ;
package main ;
use MCE::Hobo ;
use Data::Dumper ;
my $foo = Foo->new ;
my $bar = Bar->new( $foo ) ;
print Dumper( $bar->export ), "\n" ;
mce_async { $bar->task('Bar') } ;
mce_async { $bar->task('nestedFoo', 'Foo') } ;
MCE::Hobo->waitall ;
print "\n", Dumper( $bar->export ), "\n" ;
####
use strict;
use warnings;
package Foo {
use MCE::Shared ;
sub new {
my $class = shift ;
my $this = { } ;
$this->{ _SHARED_DATA } = MCE::Shared->hash( _var => 1 ) ;
bless $this, $class ;
}
sub task {
# Long operation task Foo ~ 2 seconds
my $this = shift ;
print "Starting task Foo for $_[0]\n" ;
sleep 2 ;
$this->{ _SHARED_DATA }->incr('_var') ;
print "Finished task Foo for $_[0]\n" ;
}
sub export {
my $this = shift ;
my %clone = %{ $this } ;
$clone{ _SHARED_DATA } = $this->{ _SHARED_DATA }->export(
{ unbless => 1 }
) ;
return \%clone ;
}
} ;
package Bar {
use MCE::Shared ;
use Scalar::Util 'blessed' ;
sub new {
my $class = shift ;
# This is not very realistic code.
# here it is just used as an
# example to create an object that
# contains a nested object
my $this = { nestedFoo => $_[0] } ;
$this->{ _SHARED_DATA } = MCE::Shared->hash( _var => 1 ) ;
bless $this, $class ;
}
sub task {
my $this = shift ;
if ( @_ == 2 ) {
$this->{ $_[0] }->task( $_[1] ) ;
return ;
}
# Long operation task Bar ~ 6 seconds
print "Starting task Bar for $_[0]\n" ;
sleep 6 ;
$this->{ _SHARED_DATA }->incr('_var') ;
print "Finished task Bar for $_[0]\n" ;
}
sub export {
my $this = shift ;
my %clone = %{ $this } ;
for ( keys %clone ) {
next unless blessed( $clone{ $_ } ) ;
next unless $clone{ $_ }->can('export') ;
$clone{ $_ } = $clone{ $_ }->export(
{ unbless => 1 }
) ;
}
return \%clone ;
}
} ;
package main ;
use MCE::Hobo ;
use Data::Dumper ;
my $foo = Foo->new ;
my $bar = Bar->new( $foo ) ;
print Dumper( $bar->export ), "\n" ;
mce_async { $bar->task('Bar') } ;
mce_async { $bar->task('nestedFoo', 'Foo') } ;
MCE::Hobo->waitall ;
print "\n", Dumper( $bar->export ), "\n" ;
####
$VAR1 = {
'_SHARED_DATA' => {
'_var' => 1
},
'nestedFoo' => {
'_SHARED_DATA' => {
'_var' => 1
}
}
};
Starting task Bar for Bar
Starting task Foo for Foo
Finished task Foo for Foo
Finished task Bar for Bar
$VAR1 = {
'_SHARED_DATA' => {
'_var' => 2
},
'nestedFoo' => {
'_SHARED_DATA' => {
'_var' => 2
}
}
};