NYCPHP Meetup

NYPHP.org

[nycphp-talk] pcntl_* functions.

Hans Zaunere hans at nyphp.org
Sat Oct 11 21:36:02 EDT 2003



max goldberg wrote:
> I'm using the pcntl_fork function to split up a workload between a bunch 
> of processes.
> I've managed to separate the master from the children, but I am having 
> some trouble with
> the pcntl_waitpid function.  I was wondering if anyone has any 
> documentation or examples
> of it's usage. I looked at 
> http://www.php.net/manual/en/function.pcntl-waitpid.php but it
> still isn't really clear to me.
> 
> Here is a quick script I made up:
> ---
> <?php /* -*- C++ -*- */
> 
> $max_children = 3;
> $is_daemon    = true;
> $forks        = 0;
> 
> if ($is_daemon) {
>  echo 'Master Starting Up. [' . date(' Y-m-d H:i:s ') . '] ( ' . 
> mktime() . " ) \n";
> 
>  for ($forks = 1; $forks <= $max_children; $forks++) {
> 
>    $new_pid = pcntl_fork();
> 
>    if ($new_pid == -1) {
>      die('Could not fork.');
>    }
>    else if ($new_pid != 0) {
>      echo "[ MASTER ] Starting thread with pid $new_pid ... \n";
>      $thread_list[$forks] = $new_pid;
>    }
>    else {
>      echo "[ CHILD  ]  Fork Initializing....!\n";
>      $is_daemon = false;
>      $i_am = $forks;
>      break;
>    }
>  }
> }
> 
> if ($is_daemon == true) {
>  $i_am = 0;
> }
> else {
>  $seconds = (int)($i_am * 20);
>  echo "[ CHILD  ] Sleeping for $seconds!\n";
>  sleep($seconds);
>  echo "[ CHILD  ] Done Sleeping!\n";
>  exit(1);
> }
> 
> if ($is_daemon == true) {
>  $waitpid_status = null;
>  echo "[ MASTER ] Waiting For Children to Die!\n";
>  pcntl_waitpid (-1, &$waitpid_status, WUNTRACED);
>  echo "[ MASTER ] My Children are dead!\n";
> }
> 
> ?>
> ---
> 
> The result is :
> Master Starting Up. [ 2003-10-10 12:24:17 ] ( 1065803057 )
> [ CHILD  ]  Fork Initializing....!
> [ CHILD  ] Sleeping for 20!
> [ MASTER ] Starting thread with pid 28773 ...
> [ MASTER ] Starting thread with pid 28774 ...
> [ CHILD  ]  Fork Initializing....!
> [ CHILD  ] Sleeping for 40!
> [ MASTER ] Starting thread with pid 28775 ...
> [ CHILD  ]  Fork Initializing....!
> [ CHILD  ] Sleeping for 60!
> [ MASTER ] Waiting For Children to Die!
> [ CHILD  ] Done Sleeping!
> [ MASTER ] My Children are dead!
> [max at computer:/] $ [ CHILD  ] Done Sleeping!
> [ CHILD  ] Done Sleeping!
> 
> 
> Obviously the master is only waiting for the first child to die out 
> before it responds
> that they are all done.I have a few options, one of which is keep an 
> array of the pid's
> of each fork and then loop and wait for each of them.I was just 
> wondering if it was
> possible to have it wait for any and all forked processes with one 
> command. Does
> anyone have any experience with this?

waitpid() itself takes a single process id, and so only lets the parent be aware of a single child process at a time, as you've pointed out.  Probably the correct way to handle this is using signals, since the parent gets a SIGCHLD (IIRC) when a child exits.  This might possibly help:

http://www.ecst.csuchico.edu/~beej/guide/ipc/fork.html

H




More information about the talk mailing list