ZF-8176: $parent->isRunning() never updated after child proccess fork
Description
This code I found in reference manual will never work, cose after fork child process will never change _isRunning variable in parent process and $process1->isRunning() will always return true even after child process stop running.
==================
class MyProcess extends ZendX_Console_Process_Unix { protected function _run() { for ($i = 0; $i < 10; $i++) { // Doing something really important which can't wait: sleeping sleep(1); } } }
// This part should last about 10 seconds, not 20. $process1 = new MyProcess(); $process1->start();
$process2 = new MyProcess(); $process2->start();
while ($process1->isRunning() && $process2->isRunning()) { sleep(1); }
echo 'All processes completed';
Comments
Posted by Mark Nielsen (polothy) on 2009-11-18T13:18:20.000+0000
I seem to be having the same problem, the processes run forever. I tried the ZendX_Console_Process_UnixTest::testParallel() code and it failed.
Posted by Florian Hoenig (flo) on 2009-12-31T14:18:30.000+0000
Same problem here!
Posted by Florian Hoenig (flo) on 2010-01-04T14:26:43.000+0000
This will fix the problem on OSX's WAITPID behavior (Linux not yet tested):
public function isRunning() {
$this->_isRunning = (0 == pcntl_waitpid($this->_pid, $status, WNOHANG)); return $this->_isRunning; }
Posted by Sébastien Cramatte (scramatte) on 2010-01-06T02:13:10.000+0000
The isRunning() fix seems to works under Linux too. I've tested under Debian Lenny.
Posted by Florian Hoenig (flo) on 2010-01-07T13:27:04.000+0000
Here is another fix.
shmop_read returns a string and therefore it's ($okay === "0") instead of === 0.
Looks like the class is based on PHP_Fork from PEAR. Really needs some redesign.
Posted by Ferenc Kovacs (tyrael) on 2010-03-29T05:45:58.000+0000
I've had the the same problem, it seems that the isRunning is only good for checking, whether the process started or not. So I implemented an isFinished method with a getFinished and _setFinished. isFinished() returns whether or not the process is finished running, getFinished returns when was the _setFinished called, so it can be used for measuring the execution time.
I'm gonna attach the patch.
Tyrael
Posted by Ferenc Kovacs (tyrael) on 2010-03-29T05:46:52.000+0000
isFinished, getFinished, _setFinished
Posted by Ferenc Kovacs (tyrael) on 2010-03-29T07:34:22.000+0000
sorry, I missed something from the patch. I wanted to set the actual time in the _setFinished method, so the "true" should be "time()" there.
Tyrael