Re: Monitoring multiple child processes

2009-11-11 Thread C.DeRykus
On Nov 10, 12:35 pm, shawnhco...@gmail.com (Shawn H Corey) wrote:
 C.DeRykus wrote:
  On Nov 9, 3:31 am, shawnhco...@gmail.com (Shawn H Corey) wrote:
  redo if $kid != $child_pid;

  Hm, I'm not sure why you'd want to 'redo' in the case of a
  blocking wait.  As I read the docs, a blocking wait on a
  specific pid returns only that pid if reaped normally or -1 if
  there's no such pid  (or that pid's been already reaped). In
  either case, I'd think you'd just want to continue processing
  the pid loop.

 From `perldoc -f waitpid`:

 On some systems, a value of 0 indicates that there are processes still
 running.

I see that but I suspect Perl's waitpid doc is unintentionally
misleading.
A quick look at  Linux and OpenBSD wait(2) manpages specifies a 0
return can  occur only with FLAGS set to WNOHANG.

OpenBSD: from waitpid(2) manpage:

  Otherwise, if WNOHANG is specified and there
  are no stopped or exited children, 0 is returned.

 Linux:
  ... if WNOHANG was specified and no child(ren) specified by pid
  has yet changed state, then 0 is returned.


Can anyone confirm an O/S with different semantics for wait(2)'s
return...?

 In other words, waitpid can return a value which is not the pid of the
 child you requested.  Therefore redo, since it's a foreach loop.  This,
 of course, is only true on some systems; it may not be true on yours.


If there's a system where a blocking waitpid could return something
other than -1 or the specific pid you waited on, that'd be true. But,
even then, you'd have to be careful that a -1 indicating a reaped
process didn't cause an endless loop due to the 'redo'.


--
Charles DeRykus


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




RE: Monitoring multiple child processes

2009-11-10 Thread Taylor, Andrew (ASPIRE)
On some systems, waitpid may return something rather than a child pid
or
-1.  This would happen when the wait was interrupted by something other
than a child death.  Most likely, it would be zero.

The return status, $?, is a 16-bit word of three packed values.  See
`perldoc perlvar` and search for /\$\?/.  It should be set to a
non-zero
value by the child if the child does not terminate successfully.  Most
UNIX commands do this; most user-written scripts do not.  Also, Windows
ignores the return value and always returns zero.

$? should not change unless a child process died.

Ahhh, I see.  I think I understand now.  Thankyou for your help and
explanations.

Andy


Capgemini is a trading name used by the Capgemini Group of companies which 
includes Capgemini UK plc, a company registered in England and Wales (number 
943935) whose registered office is at No. 1 Forge End, Woking, Surrey, GU21 6DB.
This message contains information that may be privileged or confidential and is 
the property of the Capgemini Group. It is intended only for the person to whom 
it is addressed. If you are not the intended recipient, you are not authorized 
to read, print, retain, copy, disseminate, distribute, or use this message or 
any part thereof. If you receive this message in error, please notify the 
sender immediately and delete all copies of this message.


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Monitoring multiple child processes

2009-11-10 Thread C.DeRykus
On Nov 9, 3:31 am, shawnhco...@gmail.com (Shawn H Corey) wrote:
 Taylor, Andrew (ASPIRE) wrote:
  Hello

  I have a script that, much like the Little Old Lady who lived in a shoe,
  has so many children it's not sure what to do.

  Basically, the script does some stuff, then kicks off multiple copies of
  an external process that all run in parallel.  It then has to wait until
  all of them have completed (successfully) then carry on with the next
  bit.

  What I've cobbled together so far (i.e. swiped of the web then
  modified...)

  use strict;
  use warnings;

  # Do some stuff here

  for (my $i=1; $i =$num_processes; $i++)

 for my $i ( 1 .. $num_processes )

  {
    defined(my $pid = fork) or die( Cannot fork : $!\n);

    # Put all the pids into an aray
    if ($pid)
    {
      push @pids, $pid;
    } else {
      exec external giggery pokery
    }
  }

  foreach my $child_pid (@pids)
  {
    waitpid($child_pid, 0);

 my $kid = waitpid($child_pid, 0);

    unless( 0==$? )
    {
      die (Oh No! An external process has failed!!\n);
    }

 redo if $kid != $child_pid;

Hm, I'm not sure why you'd want to 'redo' in the case of a
blocking wait.  As I read the docs, a blocking wait on a
specific pid returns only that pid if reaped normally or -1 if
there's no such pid  (or that pid's been already reaped). In
either case, I'd think you'd just want to continue processing
the pid loop.

In contrast (at least on POSIX compliant OS's),  a non-blocking
blocking wait with -1 rather than a specific pid  could potentially
reap other pid's:

 use POSIX :sys_wait_h;
  #...
 do {
$kid = waitpid(-1, WNOHANG);
 } while $kid  0;

This might reap an extraneous process such as one launched via
backticks maybe in an forked pid for instance.

 On some systems, waitpid may return for any interrupt, not just when the
 child terminates.

Also the POSIX non-blocking wait has the advantage in that case by
providing macro's that can reveal some additional exit/termination
status:

use POSIX :sys_wait_h;
...
$kid = waitpid( -1, WNOHANG);
print $kid: signal termination if WIFSIGNALED($?);

--
Charles DeRykus


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Monitoring multiple child processes

2009-11-10 Thread Shawn H Corey
C.DeRykus wrote:
 On Nov 9, 3:31 am, shawnhco...@gmail.com (Shawn H Corey) wrote:
 redo if $kid != $child_pid;
 
 Hm, I'm not sure why you'd want to 'redo' in the case of a
 blocking wait.  As I read the docs, a blocking wait on a
 specific pid returns only that pid if reaped normally or -1 if
 there's no such pid  (or that pid's been already reaped). In
 either case, I'd think you'd just want to continue processing
 the pid loop.

From `perldoc -f waitpid`:

On some systems, a value of 0 indicates that there are processes still
running.

In other words, waitpid can return a value which is not the pid of the
child you requested.  Therefore redo, since it's a foreach loop.  This,
of course, is only true on some systems; it may not be true on yours.


-- 
Just my 0.0002 million dollars worth,
  Shawn

Programming is as much about organization and communication
as it is about coding.

I like Perl; it's the only language where you can bless your
thingy.

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Monitoring multiple child processes

2009-11-09 Thread Shawn H Corey
Taylor, Andrew (ASPIRE) wrote:
 Hello
 
 I have a script that, much like the Little Old Lady who lived in a shoe,
 has so many children it's not sure what to do.
 
 Basically, the script does some stuff, then kicks off multiple copies of
 an external process that all run in parallel.  It then has to wait until
 all of them have completed (successfully) then carry on with the next
 bit.
 
 What I've cobbled together so far (i.e. swiped of the web then
 modified...)
 
 use strict;
 use warnings;
 
 # Do some stuff here
 
 for (my $i=1; $i =$num_processes; $i++)

for my $i ( 1 .. $num_processes )

 {
   defined(my $pid = fork) or die( Cannot fork : $!\n);
  
   # Put all the pids into an aray
   if ($pid)
   {
 push @pids, $pid;
   } else {
 exec external giggery pokery
   }
 }
 
 foreach my $child_pid (@pids)
 {
   waitpid($child_pid, 0);

my $kid = waitpid($child_pid, 0);

   unless( 0==$? )
   { 
 die (Oh No! An external process has failed!!\n);
   }

redo if $kid != $child_pid;

 }

On some systems, waitpid may return for any interrupt, not just when the
child terminates.


-- 
Just my 0.0002 million dollars worth,
  Shawn

Programming is as much about organization and communication
as it is about coding.

I like Perl; it's the only language where you can bless your
thingy.

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




RE: Monitoring multiple child processes

2009-11-09 Thread Taylor, Andrew (ASPIRE)

   my $kid = waitpid($child_pid, 0);
 
   redo if $kid != $child_pid;  # So goes back to start of loop from
here
 
   unless( 0==$? )  # And never performs this test
   { 
 die (Oh No! An external process has failed!!\n);
   }
 }
 
 
 That makes most sense to me but I'm not sure how to test if my
 assumption is correct.  (I'd have to somehow get the system to return
a
 pid/status for a different process)

In general, you will want to test for errors as soon as possible.  If
you get an error, how do you know waitpid will ever work correctly
again?

OK, I'm clearly being dense here then.  My understanding was that the
$? contained the status of the pid returned by waidpid.  

If waitpid returned a pid from some other process (i.e. not one of my
children) that had failed (i.e return status other than 0) then wouldn't
my test abort the script when it wouldn't need to (as the process that
failed wasn't one of my children) before it got to the redo?

Or have I firmly grasped the wrong end of the stick?





Capgemini is a trading name used by the Capgemini Group of companies which 
includes Capgemini UK plc, a company registered in England and Wales (number 
943935) whose registered office is at No. 1 Forge End, Woking, Surrey, GU21 6DB.
This message contains information that may be privileged or confidential and is 
the property of the Capgemini Group. It is intended only for the person to whom 
it is addressed. If you are not the intended recipient, you are not authorized 
to read, print, retain, copy, disseminate, distribute, or use this message or 
any part thereof. If you receive this message in error, please notify the 
sender immediately and delete all copies of this message.


--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/




Re: Monitoring multiple child processes

2009-11-09 Thread Shawn H Corey
Taylor, Andrew (ASPIRE) wrote:
 OK, I'm clearly being dense here then.  My understanding was that the
 $? contained the status of the pid returned by waidpid.  
 
 If waitpid returned a pid from some other process (i.e. not one of my
 children) that had failed (i.e return status other than 0) then wouldn't
 my test abort the script when it wouldn't need to (as the process that
 failed wasn't one of my children) before it got to the redo?
 
 Or have I firmly grasped the wrong end of the stick?

On some systems, waitpid may return something rather than a child pid or
-1.  This would happen when the wait was interrupted by something other
than a child death.  Most likely, it would be zero.

The return status, $?, is a 16-bit word of three packed values.  See
`perldoc perlvar` and search for /\$\?/.  It should be set to a non-zero
value by the child if the child does not terminate successfully.  Most
UNIX commands do this; most user-written scripts do not.  Also, Windows
ignores the return value and always returns zero.

$? should not change unless a child process died.


-- 
Just my 0.0002 million dollars worth,
  Shawn

Programming is as much about organization and communication
as it is about coding.

I like Perl; it's the only language where you can bless your
thingy.

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/