diff --git a/lib/MCE.pm b/lib/MCE.pm index 5bc625b..147e316 100644 --- a/lib/MCE.pm +++ b/lib/MCE.pm @@ -121,7 +121,7 @@ BEGIN { return $self->{$_p}; }; } - for my $_p (qw( chunk_id task_id task_wid wid )) { + for my $_p (qw( chunk_id seed task_id task_wid wid )) { *{ $_p } = sub () { my $self = shift; $self = $MCE unless ref($self); return $self->{"_${_p}"}; @@ -641,25 +641,7 @@ sub spawn { for (0 .. $_max_workers - 1); } - # The PDL module 2.062 ~ 2.089 exports its own srand() function, that - # silently clobbers Perl's srand function, and does not seed Perl's - # pseudo-random generator. https://perlmonks.org/?node_id=11159773 - - if ( $INC{'PDL/Primitive.pm'} ) { - # Call PDL's random() function if exported i.e. use PDL. - - my $caller = caller(); local $@; - $caller = caller(1) if ( $caller =~ /^MCE/ ); - $caller = caller(2) if ( $caller =~ /^MCE/ ); - $caller = caller(3) if ( $caller =~ /^MCE/ ); - - $self->{_seed} = eval "$caller->can('random')" - ? int(PDL::Primitive::random() * 1e9) - : int(CORE::rand() * 1e9); - } - else { - $self->{_seed} = int(CORE::rand() * 1e9); - } + $self->{_seed} = int(CORE::rand() * 1e9); ## ------------------------------------------------------------------------- @@ -1609,8 +1591,7 @@ sub sess_dir { return $self->{_sess_dir} if defined $self->{_sess_dir}; if ($self->{_wid} == 0) { - $self->{_sess_dir} = $self->{_spawned} - ? _make_sessdir($self) : undef; + $self->{_sess_dir} = $self->{_spawned} ? _make_sessdir($self) : undef; } else { my $_chn = $self->{_chn}; @@ -2033,17 +2014,15 @@ sub _dispatch { MCE::Hobo->_clear() if $INC{'MCE/Hobo.pm'}; } - # Sets the seed of the base generator uniquely between workers. + # Set the seed of the base generator uniquely between workers. # The new seed is computed using the current seed and ID value. # One may set the seed at the application level for predictable # results (non-thread workers only). Ditto for Math::Prime::Util, # Math::Random, Math::Random::MT::Auto, and PDL. # - # MCE 1.892, 2024-06-08 - # Removed check if spawning threads i.e. use_threads. - # Predictable output matches non-threads for CORE, - # Math::Prime::Util, and Math::Random::MT::Auto. - # https://perlmonks.org/?node_id=11159834 + # MCE 1.892, 2024-06-08: Enable predictability running threads. + # Output matches non-threads for CORE, Math::Prime::Util, and + # Math::Random::MT::Auto. https://perlmonks.org/?node_id=11159834 { my $_wid = $_args[1]; diff --git a/lib/MCE/Child.pm b/lib/MCE/Child.pm index f62054a..8b8c22f 100644 --- a/lib/MCE/Child.pm +++ b/lib/MCE/Child.pm @@ -111,25 +111,7 @@ sub init { $_DATA->{ $pkg } = MCE::Child::_hash->new( $chnl ); $_DATA->{"$pkg:id"} = 0; - # The PDL module 2.062 ~ 2.089 exports its own srand() function, that - # silently clobbers Perl's srand function, and does not seed Perl's - # pseudo-random generator. https://perlmonks.org/?node_id=11159773 - - if ( $INC{'PDL/Primitive.pm'} ) { - # Call PDL's random() function if exported i.e. use PDL. - - my $caller = caller(); local $@; - $caller = caller(1) if ( $caller =~ /^MCE/ ); - $caller = caller(2) if ( $caller =~ /^MCE/ ); - $caller = caller(3) if ( $caller =~ /^MCE/ ); - - $_DATA->{"$pkg:seed"} = eval "$caller->can('random')" - ? int(PDL::Primitive::random() * 1e9) - : int(CORE::rand() * 1e9); - } - else { - $_DATA->{"$pkg:seed"} = int(CORE::rand() * 1e9); - } + $_DATA->{"$pkg:seed"} = int(CORE::rand() * 1e9); $MCE::_GMUTEX->unlock() if ( $_tid && $MCE::_GMUTEX ); } @@ -264,7 +246,7 @@ sub create { MCE::Child->_clear() if $INC{'MCE/Child.pm'}; MCE::Hobo->_clear() if $INC{'MCE/Hobo.pm'}; - # Sets the seed of the base generator uniquely between workers. + # Set the seed of the base generator uniquely between workers. # The new seed is computed using the current seed and ID value. # One may set the seed at the application level for predictable # results. Ditto for PDL, Math::Prime::Util, Math::Random, and @@ -559,6 +541,13 @@ sub result { wantarray ? @{ delete $self->{RESULT} } : delete( $self->{RESULT} )->[-1]; } +sub seed { + _croak('Usage: MCE::Child->seed()') if ref($_[0]); + my $pkg = exists $_SELF->{PKG} ? $_SELF->{PKG} : "$$.$_tid.".caller(); + + return $_DATA->{"$pkg:seed"}; +} + sub self { ref($_[0]) ? $_[0] : $_SELF; } @@ -1543,6 +1532,13 @@ C aware. my @res2 = $child2->result(); # ( foo ) my $res2 = $child2->result(); # foo +=item MCE::Child->seed() + +Class method that returns the internal random generated seed or undefined. +The seed is generated once during init or initial create. + +Current API available since 1.895. + =item MCE::Child->self() Class method that allows a child to obtain it's own I object. diff --git a/lib/MCE/Core.pod b/lib/MCE/Core.pod index 256bfd2..89fe35c 100644 --- a/lib/MCE/Core.pod +++ b/lib/MCE/Core.pod @@ -1474,6 +1474,15 @@ Sending to C { File, Pipe, STDIO } is supported since MCE 1.845. MCE->say($out, "sent to stdout"); MCE->say($err, "sent to stderr"); +=head2 MCE->seed ( void ) + +=head2 $mce->seed ( void ) + +Returns the internal random generated seed or undefined. +The seed is generated each time, prior to spawning a MCE session. + +Current API available since 1.895. + =head2 MCE->sess_dir ( void ) =head2 $mce->sess_dir ( void ) diff --git a/lib/MCE/Subs.pm b/lib/MCE/Subs.pm index 2410f1f..9293ece 100644 --- a/lib/MCE/Subs.pm +++ b/lib/MCE/Subs.pm @@ -102,6 +102,7 @@ sub mce_chunk_size ( ) { return $MCE::MCE->chunk_size(); } sub mce_max_retries ( ) { return $MCE::MCE->max_retries(); } sub mce_max_workers ( ) { return $MCE::MCE->max_workers(); } sub mce_pid ( ) { return $MCE::MCE->pid(); } +sub mce_seed ( ) { return $MCE::MCE->seed(); } sub mce_sess_dir ( ) { return $MCE::MCE->sess_dir(); } sub mce_task_id ( ) { return $MCE::MCE->task_id(); } sub mce_task_name ( ) { return $MCE::MCE->task_name(); } @@ -176,6 +177,7 @@ sub _export_subs { *{ $_package . '::mce_max_retries' } = \&mce_max_retries; *{ $_package . '::mce_max_workers' } = \&mce_max_workers; *{ $_package . '::mce_pid' } = \&mce_pid; + *{ $_package . '::mce_seed' } = \&mce_seed; *{ $_package . '::mce_sess_dir' } = \&mce_sess_dir; *{ $_package . '::mce_task_id' } = \&mce_task_id; *{ $_package . '::mce_task_name' } = \&mce_task_name; @@ -371,6 +373,8 @@ MCE methods are described in L. =item * mce_pid +=item * mce_seed + =item * mce_sess_dir =item * mce_task_id