Re: [PHP] Fork and zombies

2009-03-17 Thread Per Jessen
Waynn Lue wrote:

 Here's pseudo code for what I'm trying to do:
 
 foreach ($things as $thing) {
 info = getInfo($thing); // uses a db connection
 makeApiCall(info);
 }
 
 makeApiCall(info) {
   $pid = pcntl_fork();
   if ($pid == -1) {
 die(could not fork);
   } else if ($pid) {
 // parent, return the child pid
 echo child pid $pid\n;
 return;
   } else {
 // do some api calls
exit;
   }
 }
 
 But after I spawn off the process, getInfo($thing) errors out sometime
 later on with an invalid query error, because I think the db
 connection is gone.  I thought adding exit in the child process
 would be enough, but that doesn't seem to work, I still get the same
 error.  Why would the child process affect the query in the parent
 process, especially if I exit in the child process?

First things first - I would add a pcntl_wait like this:

foreach ($things as $thing) {
info = getInfo($thing); // uses a db connection
makeApiCall(info);
  switch( $p=pcntl_wait( $stat, WNOHANG ) )
  {
case -1:  echo some sort of error in pcntl_wait()\n; break;
case 0: break;
default:
   echo child $p finished\n;
  }
}


Second, it sounds like you're expecting to reuse your database
connection from getInfo() in the child you're forking in makeAPIcall()? 
I don't think that really works - I think you need a new connection per
child.


/Per


-- 
Per Jessen, Zürich (3.9°C)


--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Fork and zombies

2009-03-17 Thread Waynn Lue

  Here's pseudo code for what I'm trying to do:
 
  foreach ($things as $thing) {
  info = getInfo($thing); // uses a db connection
  makeApiCall(info);
  }
 
  makeApiCall(info) {
$pid = pcntl_fork();
if ($pid == -1) {
  die(could not fork);
} else if ($pid) {
  // parent, return the child pid
  echo child pid $pid\n;
  return;
} else {
  // do some api calls
 exit;
}
  }
 
  But after I spawn off the process, getInfo($thing) errors out sometime
  later on with an invalid query error, because I think the db
  connection is gone.  I thought adding exit in the child process
  would be enough, but that doesn't seem to work, I still get the same
  error.  Why would the child process affect the query in the parent
  process, especially if I exit in the child process?

 First things first - I would add a pcntl_wait like this:

 foreach ($things as $thing) {
 info = getInfo($thing); // uses a db connection
 makeApiCall(info);
   switch( $p=pcntl_wait( $stat, WNOHANG ) )
  {
case -1:  echo some sort of error in pcntl_wait()\n; break;
case 0: break;
default:
   echo child $p finished\n;
  }
 }


I actually tried this in the meantime:

  $pid = pcntl_fork();
  if ($pid == -1) {
die(could not fork);
  } else if ($pid) {
// parent, return the child pid
echo child pid $pid waiting\n;
pcntl_waitpid($pid, $status);
if (pcntl_wifexited($status)) {
  echo finished [$status] waiting\n;
  return;
} else {
  echo ERROR\n;
}


But it still has the same problem, and I'm also trying to avoid pcntl_wait
or pcntl_waitpid at all because I still want to do it asynchronously.  I
even tried rewriting it do return $pid in the parent thread, and then
aggregate them at the calling function level, and then loop through them all
with pcntl_waitpid, but that didn't work either.




 Second, it sounds like you're expecting to reuse your database
 connection from getInfo() in the child you're forking in makeAPIcall()?
 I don't think that really works - I think you need a new connection per
 child.


Oh, in this case, I don't do anything with the database at all in the child
thread.  I was worried there would be some errors there so I actually
commented out all db accesses in the child thread, but it still somehow
closes the parent's db connection (or at least causes the query not to work,
somehow).


Re: [PHP] Fork and zombies

2009-03-17 Thread Per Jessen
Waynn Lue wrote:

 I actually tried this in the meantime:
 
   $pid = pcntl_fork();
   if ($pid == -1) {
 die(could not fork);
   } else if ($pid) {
 // parent, return the child pid
 echo child pid $pid waiting\n;
 pcntl_waitpid($pid, $status);
 if (pcntl_wifexited($status)) {
   echo finished [$status] waiting\n;
   return;
 } else {
   echo ERROR\n;
 }
 

I think your waitpid() is in the wrong place, and at least you need use
WNOHANG - unless you specifically want to wait for each child to finish
before starting another one.

 But it still has the same problem, and I'm also trying to avoid
 pcntl_wait or pcntl_waitpid at all because I still want to do it
 asynchronously.  

pcntl_wait(WNOHANG) will make everything work asynchronously.


/Per

-- 
Per Jessen, Zürich (5.8°C)


--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Fork and zombies

2009-03-17 Thread Per Jessen
Waynn Lue wrote:

 Ah, I was changing it to waiting for each child to finish in order to
 see if I could narrow down my db problem, because I figure this should
 be more or
 less equivalent to running it synchronously.  Even like this, though,
 it still causes the db problem.

I think the database problem is caused by your child inheriting the
connection, and then closing it - whilst the parent is still using it. 
Your parent needs to open a new connection.


/Per

-- 
Per Jessen, Zürich (8.8°C)


--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Fork and zombies

2009-03-17 Thread Waynn Lue

 I think your waitpid() is in the wrong place, and at least you need use
 WNOHANG - unless you specifically want to wait for each child to finish
 before starting another one.

  But it still has the same problem, and I'm also trying to avoid
  pcntl_wait or pcntl_waitpid at all because I still want to do it
  asynchronously.

 pcntl_wait(WNOHANG) will make everything work asynchronously.


Ah, I was changing it to waiting for each child to finish in order to see if
I could narrow down my db problem, because I figure this should be more or
less equivalent to running it synchronously.  Even like this, though, it
still causes the db problem.


Re: [PHP] Fork and zombies

2009-03-16 Thread Per Jessen
Waynn Lue wrote:

 I periodically run a script that makes a call against a remote API,
 which
 takes some time to return.  In an attempt to increase thoroughput, I
 decided to investigate using pnctl_fork to spawn off multiple
 processes to make the call, since the slowest part is the network part
 of it (and waiting for the
 server response).  I ended up writing a script that did this:
 
 $pid = pnctl_fork();
   if ($pid == -1) {
 die('could not fork');
   } else if ($pid) {
 echo parent $pid\n;
 return;
   } else {
 // make API call
   }
 
 While this works, it unfortunately leaves behind a zombie process
 every single time. 

You need to call pcntl_wait() or pcntl_waitpid(). 


/Per


-- 
Per Jessen, Zürich (4.2°C)


--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Fork and zombies

2009-03-16 Thread Waynn Lue

 Waynn Lue wrote:

  I periodically run a script that makes a call against a remote API,
  which
  takes some time to return.  In an attempt to increase thoroughput, I
  decided to investigate using pnctl_fork to spawn off multiple
  processes to make the call, since the slowest part is the network part
  of it (and waiting for the
  server response).  I ended up writing a script that did this:
 
  $pid = pnctl_fork();
if ($pid == -1) {
  die('could not fork');
} else if ($pid) {
  echo parent $pid\n;
  return;
} else {
  // make API call
}
 
  While this works, it unfortunately leaves behind a zombie process
  every single time.

 You need to call pcntl_wait() or pcntl_waitpid().


Right, but if I do that, then the parent has to wait until the child
completes before it exits.  Is there any way to have the parent exit before
the child but prevent the zombie process for existing?


Re: [PHP] Fork and zombies

2009-03-16 Thread Per Jessen
Waynn Lue wrote:

  While this works, it unfortunately leaves behind a zombie process
  every single time.

 You need to call pcntl_wait() or pcntl_waitpid().

 
 Right, but if I do that, then the parent has to wait until the child
 completes before it exits.  

No it doesn't - just call pcntl_wait() with WNOHANG to check the status
of a child. 


/Per

-- 
Per Jessen, Zürich (6.5°C)


--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Fork and zombies

2009-03-16 Thread Waynn Lue

   While this works, it unfortunately leaves behind a zombie process
   every single time.
 
  You need to call pcntl_wait() or pcntl_waitpid().
 
 
  Right, but if I do that, then the parent has to wait until the child
  completes before it exits.

 No it doesn't - just call pcntl_wait() with WNOHANG to check the status
 of a child.


Hm, so now I'm not so sure what's happening.  Before trying your suggestion,
I ran my script again without pcntl_wait so that I'd have a baseline for how
many zombie processes are being created, and it turns out that I don't think
any are.  Previously, I was doing

ps aux | awk '{ print $8   $2 }' | grep -w Z

to find zombie processes, and it turns out that they existed from before, as
the count didn't change after I ran my script.  That leads to another
problem, though, in that the resource for the database doesn't seem to be
available for the parent after the child exits.  Here's pseudo code for what
I'm trying to do:

foreach ($things as $thing) {
info = getInfo($thing); // uses a db connection
makeApiCall(info);
}

makeApiCall(info) {
  $pid = pcntl_fork();
  if ($pid == -1) {
die(could not fork);
  } else if ($pid) {
// parent, return the child pid
echo child pid $pid\n;
return;
  } else {
// do some api calls
   exit;
  }
}

But after I spawn off the process, getInfo($thing) errors out sometime later
on with an invalid query error, because I think the db connection is
gone.  I thought adding exit in the child process would be enough, but
that doesn't seem to work, I still get the same error.  Why would the child
process affect the query in the parent process, especially if I exit in the
child process?

Following your suggestion, I also tried pcntl_wait in the upperlevel
function, but still had the same problem.

Thanks for any insight,
Waynn


Re: [PHP] fork/spawnzombie question

2009-02-13 Thread Per Jessen
bruce wrote:

 Hi Nathan/Torok...
 
 Hey guys... got a bit of a question.
 
 I'm playing around with the php/for/pcntl_exec functions and I've got
 a process that spawns off a bunch of child processes. Unfortunately,
 I'm getting to where I have 100's of zombie child processes that I can
 see from the linux/processTBL.
 
 I don't want to have my master loop do a waitpid() call, as it would
 block on the wait for one of the child processes to exit. 

No, it wouldn't - just use WNOHANG:

pcntl_waitpid( -1, $status, WNOHANG );


/Per Jessen


-- 
Per Jessen, Zürich (-0.9°C)


--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Fork PHP script X at a time.

2004-09-21 Thread John Wards
Not sure if anyone is interested in what I have come up with, its busy
running just now but it seems to be performing ok.

$do =0;
$ok =0;
$count=0;

while($do!=1){
if($ok==0){
$sql = SELECT * FROM locations WHERE parent = '0' AND doing=0 and 
done !=1 ORDER BY num DESC LIMIT 0 , 1;
$res = mysql_query($sql) or die ($sql.mysql_error());
while($_data = mysql_fetch_array($res)){
$id = $county_data[id];
$sql2 = UPDATE locations SET doing = 1 WHERE id= '$id' AND 
siteid=1 AND parent = '0';
$res3 = mysql_query($sql2);
exec(/usr/local/bin/php fork.php .$data[id].  /dev/null 
);
}
}
$sql = SELECT * FROM locations WHERE parent = '0' AND doing=1 AND done=0;
$res = mysql_query($sql);
$oknumber = mysql_num_rows($res);
if($oknumber == 5) $ok=1;
else $ok=0;

$sql = SELECT * FROM locations WHERE parent = '0' AND done=0;
$res2 = mysql_query($sql);
$donumber = mysql_num_rows($res2);
if($donumber==0) $do=1;
}

In my fork.php script I set it to done=1 and doing = 0 once it has
finished.

This is pretty rough and ready and as my shell account won't let me do a
top i can't tell what sort of drain my loop is having on the system,
but hopefully it will be ok.

Just thought it might be an idea to post up this solution in-case
someone else has the same problem.

John
On Mon, 2004-09-20 at 16:36, John Wards wrote:
 Hi, I have a bit of a cold today so I probably would have figured this
 out for myself eventually but hey ;-)
 
 Right I have a script that I need to run around 90 times thru a cron job
 but passing a different i.d. to it each time.
 
 I have experimented with running all 90 at once and its a no go as it
 just makes the server run to slow and the session cookies I use time out
 (I am doing some libcurl things).
 
 Also running them in a loop one at a time is no use because it takes
 about 8 hours.
 
 What I would like to do is fork off say 5-10 at a time and when one is
 done start another one in its place, as they all take different length
 of times to compleate.
 
 Any clues at where to start? Here is my fork all 90+ code...
 
 
 $sql = SELECT * FROM locations WHERE parent = '0';
 $res = mysql_query($sql) or die ($sql.mysql_error());
 while($data = mysql_fetch_array($res)){
   exec(/usr/local/bin/php fork.php .$_data[id].  /dev/null );
 }
 
 Cheers
 John Wards

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Fork PHP script X at a time.

2004-09-21 Thread John Wards
On Tue, 2004-09-21 at 13:58, John Wards wrote:
 Not sure if anyone is interested in what I have come up with, its busy
 running just now but it seems to be performing ok.

Again adding to this thread for future reference.

Its just compleated all 90 threads in 1 hour 50 minutes and that was
running 5 at a time.

Very sucessful bit of code, I'm quite cuffed ;-)

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Fork PHP script X at a time.

2004-09-20 Thread Wouter van Vliet
 Hi, I have a bit of a cold today so I probably would have figured this
 out for myself eventually but hey ;-)
 
 Right I have a script that I need to run around 90 times thru a cron job
 but passing a different i.d. to it each time.
 
 I have experimented with running all 90 at once and its a no go as it
 just makes the server run to slow and the session cookies I use time out
 (I am doing some libcurl things).
 
 Also running them in a loop one at a time is no use because it takes
 about 8 hours.
 
 What I would like to do is fork off say 5-10 at a time and when one is
 done start another one in its place, as they all take different length
 of times to compleate.
 
 Any clues at where to start? Here is my fork all 90+ code...
 
 $sql = SELECT * FROM locations WHERE parent = '0';
 $res = mysql_query($sql) or die ($sql.mysql_error());
 while($data = mysql_fetch_array($res)){
exec(/usr/local/bin/php fork.php .$_data[id].  /dev/null );
 }

You should be able to find out about the PID's for every forked
process, and use a loop (advisable with a sleep() in it) to see how
many procs are still running.. When the amount drops somewhat, spawn
another ..

Hope will get you somewhere!

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Fork PHP script X at a time.

2004-09-20 Thread John Wards
On Mon, 2004-09-20 at 16:45, Wouter van Vliet wrote:
  
  What I would like to do is fork off say 5-10 at a time and when one is
  done start another one in its place, as they all take different length
  of times to compleate.
  
  Any clues at where to start? Here is my fork all 90+ code...
  
  $sql = SELECT * FROM locations WHERE parent = '0';
  $res = mysql_query($sql) or die ($sql.mysql_error());
  while($data = mysql_fetch_array($res)){
 exec(/usr/local/bin/php fork.php .$_data[id].  /dev/null );
  }
 
 You should be able to find out about the PID's for every forked
 process, and use a loop (advisable with a sleep() in it) to see how
 many procs are still running.. When the amount drops somewhat, spawn
 another ..

Hmm, first off how would I get the PID for each process?

I could store each PID and then sleep for a minute, then check to see if
those PIDs are still valid (How would I do that?!) then fork some more
and loop till fade...

Think I will sleep on it.

John

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Fork PHP script X at a time.

2004-09-20 Thread Marek Kilimajer
play around with popen() and stream_select()
John Wards wrote:
Hi, I have a bit of a cold today so I probably would have figured this
out for myself eventually but hey ;-)
Right I have a script that I need to run around 90 times thru a cron job
but passing a different i.d. to it each time.
I have experimented with running all 90 at once and its a no go as it
just makes the server run to slow and the session cookies I use time out
(I am doing some libcurl things).
Also running them in a loop one at a time is no use because it takes
about 8 hours.
What I would like to do is fork off say 5-10 at a time and when one is
done start another one in its place, as they all take different length
of times to compleate.
Any clues at where to start? Here is my fork all 90+ code...
$sql = SELECT * FROM locations WHERE parent = '0';
$res = mysql_query($sql) or die ($sql.mysql_error());
while($data = mysql_fetch_array($res)){
exec(/usr/local/bin/php fork.php .$_data[id].  /dev/null );
}
Cheers
John Wards
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


Re: [PHP] Fork PHP script X at a time.

2004-09-20 Thread John Wards
On Mon, 2004-09-20 at 16:56, Marek Kilimajer wrote:
 play around with popen() and stream_select()

Oooh that looks handy.

More night time reading I think!

Any further ideas to save a man with a cold from using his brain would
be great!

Cheers
John

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Fork PHP script X at a time.

2004-09-20 Thread raditha dissanayake
John Wards wrote:
Hi, I have a bit of a cold today so I probably would have figured this
out for myself eventually but hey ;-)
Right I have a script that I need to run around 90 times thru a cron job
but passing a different i.d. to it each time.
 

not suprised.
I have experimented with running all 90 at once and its a no go as it
just makes the server run to slow and the session cookies I use time out
(I am doing some libcurl things).
Also running them in a loop one at a time is no use because it takes
about 8 hours.
 

if your script consumes lots of CPU, lots of memory, lots of bandwidth 
or any combination of these you may not see a significant improvement by 
using threads. If you sleep you might find that the total running time 
will actually increase, so this is something you might want to go about 
carefully. PHP isn't the easiest language to use when you have to do 
your own threading but since others have already given good advice on 
the howto i will refrain from adding my 0.02


--
Raditha Dissanayake.

http://www.radinks.com/sftp/ | http://www.raditha.com/megaupload
Lean and mean Secure FTP applet with | Mega Upload - PHP file uploader
Graphical User Inteface. Just 128 KB | with progress bar.
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


Re: [PHP] Fork PHP script X at a time.

2004-09-20 Thread Greg Donald
On Mon, 20 Sep 2004 16:36:51 +0100, John Wards [EMAIL PROTECTED] wrote:
 Right I have a script that I need to run around 90 times thru a cron job
 but passing a different i.d. to it each time.
 
 I have experimented with running all 90 at once and its a no go as it
 just makes the server run to slow and the session cookies I use time out
 (I am doing some libcurl things).
 
 Also running them in a loop one at a time is no use because it takes
 about 8 hours.
 
 What I would like to do is fork off say 5-10 at a time and when one is
 done start another one in its place, as they all take different length
 of times to compleate.
 
 Any clues at where to start? Here is my fork all 90+ code...
 
 $sql = SELECT * FROM locations WHERE parent = '0';
 $res = mysql_query($sql) or die ($sql.mysql_error());
 while($data = mysql_fetch_array($res)){
 exec(/usr/local/bin/php fork.php .$_data[id].  /dev/null );

I'd write a scheduler.  Insert the jobs into the database whenever
they need to run.  Then have a script that runs via cron that will
monitor system load, and start and stop jobs as required.

http://pear.php.net/package/System_ProcWatch


-- 
Greg Donald
http://gdconsultants.com/
http://destiney.com/

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Fork PHP script X at a time.

2004-09-20 Thread Marek Kilimajer
John Wards wrote:
On Mon, 2004-09-20 at 16:56, Marek Kilimajer wrote:
play around with popen() and stream_select()

Oooh that looks handy.
More night time reading I think!
Any further ideas to save a man with a cold from using his brain would
be great!
Cheers
John
Wanted to do something interesting, so here is something to get you 
started. It opens a pool of 10 sleep processes that sleep for a random 
time. Everytime a sleep process ends its sleep and exits, a new sleep 
process is created.

However, it contains some very, very ugly hack. stream_select() breaks 
index association of its parameters, so to find out what stream changed 
status one has to compare values of the original array ($handles) and 
the array passed to stream_select() ($read).

Is it how it's supposed to work or am I missing something?
?php
$handles = array();
for($i = 0; $i  10; $i++) {
  $handles[$i] = popen('sleep ' . rand(1, 10), 'r');
  echo Opened '$handles[$i]'\n;
}
while(count($handles)) {
  $read = $handles;
  if (false === ($num_changed_streams = stream_select($read, $write = 
NULL, $except = NULL, 10))) { // don't forget to change tv_sec param
 /* Error handling */
 echo ERROR\n;
  } elseif ($num_changed_streams  0) {

 foreach($read as $key = $handle) {
   echo Closing '$handle'\n;
   //echo fread($handle, 2096);
   pclose($handle);
   if($i  50) {
 $handles[$i] = popen('sleep ' . rand(1, 10), 'r');
 echo Opened '$handles[$i]'\n;
 $i++;
   }
 }
 // UGLY hack here
 $handles = array_diff($handles, $read);
  }
}
?
--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


Re: [PHP] Fork and multi-thread in PHP?

2002-06-12 Thread Rasmus Lerdorf

That's one of the main reasons you would want to use the mail() function.
I wouldn't advise a fork() here, but if you really insist, see the pcntl
extension - http://php.net/pcntl

-Rasmus

On Wed, 12 Jun 2002, Nathan Cassano wrote:


 Hi PHP folks,
   I have a program that sends out email by making socket
 connection to our email server. The problem is that the program is very
 slow because it has to finish talking to the email server until it can
 proceed with the next email (as opposed to the mail() function that just
 forks off a sendmail process). Is there a way for PHP to fork or
 multi-thread to do I/O?


 --
 PHP General Mailing List (http://www.php.net/)
 To unsubscribe, visit: http://www.php.net/unsub.php



-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php




Re: [PHP] fork?

2002-02-23 Thread Andrey Hristov

Vulcan Logic SRM
www.vl-srm.net

Every your task is a banana.

Regards,
Andrey Hristov

- Original Message - 
From: Paul Roberts [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Sent: Saturday, February 23, 2002 1:05 PM
Subject: [PHP] fork?


how do i do two things at the same time, i'm thinking of the equivalent of fork in perl


Paul Roberts
[EMAIL PROTECTED]



-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php




-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php