Hello Mario,
(BTW you mentioned that having the signal handlers as well as END may be overdone ... the reason I have the data dumped in END is so it prints out upon uncaught exception.)
I made the change to MCE::Shared::Server as instructed. I took your last script (in the post I am replying to) and modified slightly. First, took some of the debug statements away and cleaned up others. Second, only dump the data in INT from parent process (as you have it in END). This gives following results:
With CTL-C, the END block is never reached by the parent; only the children. But the parent dumps the data in INT.
perl mce9.pl
Parent PID 11581
worker 2 (11584) processing chunk 1
worker 1 (11583) processing chunk 2
worker 1 (11583) processing chunk 4
worker 2 (11584) processing chunk 3
^CHello from INT: 11584
Hello from INT: 11581
Hello from END block: 11584
Parent in INT: $VAR1 = bless( {
'00 11584' => '1491592596',
'01 11583' => '1491592596',
'02 11584' => '1491592598',
'03 11583' => '1491592598'
}, 'MCE::Shared::Hash' );
## mce9.pl: caught signal (INT), exiting
Hello from INT: 11583
Hello from END block: 11583
Killed
When running to completion, the parent reaches the END block and dumps the data there:
perl mce9.pl
Parent PID 11554
worker 2 (11557) processing chunk 1
worker 1 (11556) processing chunk 2
worker 2 (11557) processing chunk 3
worker 1 (11556) processing chunk 4
worker 1 (11556) processing chunk 6
worker 2 (11557) processing chunk 5
worker 1 (11556) processing chunk 7
Hello from END block: 11557
Hello from END block: 11556
Hello from END block: 11554
Parent in END: $VAR1 = bless( {
'00 11557' => '1491592580',
'01 11556' => '1491592580',
'02 11557' => '1491592582',
'03 11556' => '1491592582',
'04 11557' => '1491592584',
'05 11556' => '1491592584',
'06 11556' => '1491592586'
}, 'MCE::Shared::Hash' );
Regarding END blocks, I believe Perl does guarantee the order (unlike BEGIN), which is Last In First Out. So the END block in the script should be executed before the one in a module that is loaded by
use.
Code now:
use strict; use warnings; use feature 'say';
use Data::Dumper; ++$Data::Dumper::Sortkeys;
use MCE::Loop;
use MCE::Shared;
$|++;
my $pid = $$; say "Parent PID $pid";
my $hash = MCE::Shared->hash();
$SIG{'INT'} = $SIG{'TERM'} = sub {
my $signal = shift; $SIG{'INT'} = $SIG{'TERM'} = sub {};
say "Hello from $signal: $$";
if ( $$ == $pid ) {
say 'Parent in INT: ' . Dumper $hash->export;
}
MCE::Signal::stop_and_exit('INT');
};
MCE::Loop->init(
max_workers => 2, chunk_size => 1, user_begin => sub {
$SIG{'INT'} = sub {
my $signal = shift;
say "Hello from $signal: $$";
MCE->exit(0);
};
$SIG{'TERM'} = sub {
my $signal = shift;
say "Hello from $signal: $$";
MCE::Signal::stop_and_exit($signal);
};
}
);
mce_loop {
my ( $mce, $chunk_ref, $chunk_id ) = @_;
say sprintf 'worker %s (%s) processing chunk %s', MCE->wid, MCE->p
+id, $chunk_id;
for ( @{ $chunk_ref } ) {
$hash->{ sprintf '%.2d %s', $_, $$ } = time;
sleep 2;
}
} ( 0 .. 6 );
MCE::Loop->finish;
END {
say "Hello from END block: $$";
if ( $$ == $pid ) {
say 'Parent in END: ' . Dumper $hash->export;
}
}
Thank you again.
The way forward always starts with a minimal test.