I am trying to start a child process from parent when its terminated normally or due to an error.Using pcntl_waitpid, It become possible to get status from child. By that status I want restart the same script or process again. Here is an example.
<?php
for ($i = 1; $i <= 5; ++$i) {
$pid = pcntl_fork();
if (!$pid) {
sleep(1);
print "In child $i\n";
exit($i);
}
}
while (pcntl_waitpid(0, $status) != -1) {
$status = pcntl_wexitstatus($status);
echo "Child $status completed\n";
}
?>
How can it possible? Thanks in advance.
Try
echo $i;
break;
instead
exit($i);
Related
I am running this via the command line. When the loop is running, is there any way I can pause the execution of the code? Ideal case would be that I could press a key to pause and then another key to resume. If I don't press the pause key then the loop continues until $i == 1000
<?php
echo "How long should the code sleep between increments?\n";
echo ">> ";
$sleep = trim(fgets(STDIN));
for ($i = 1; $i <= 1000; $i++) {
echo "$i\n";
sleep($sleep);
}
This is a heavily simplified example of my actual need for the code.
I don't sure my code is best solution or not but it work.
function checkResume()
{
$r = false;
while (!$r) {
if (fgets(STDIN) == "r") {
$r = true;
}
}
}
function checkPause()
{
$input = fgets(STDIN);
if (!empty($input) && $input == "p") {
return true;
}
return false;
}
echo "How long should the code sleep between increments?\n";
echo ">> ";
$sleep = trim(fgets(STDIN));
echo "\nStart ...\n";
stream_set_blocking(STDIN, false);
for ($i = 1; $i <= 1000; $i++) {
if (checkPause()) {
echo "wait for resume \n";
checkResume();
}
echo "$i\n";
sleep($sleep);
}
Hope this help.
I'm starting 10 processes asynchronously:
$procs = [];
for($i = 0; $i < 10; $i++) {
$proc = new Process('ls -lsa');
$proc->start();
$procs[$i] = $proc;
}
Now i want to wait asynchronous for every process to finish and print out state informations while waiting:
foreach($procs as $proc) {
$proc->wait(function ($type, $buffer) {
if (Process::ERR === $type) {
// Print out error ...
} else {
// Print out state informations ...
});
}
}
The Problem is at the wait function. It waits for the task to finish and then go on to the next tasks. But i want this to run asynchronous.
How can i do this?
Thanks !
As per the Symfony docs the wait method is blocking and therefore will wait until that process is finished before continuing.
If you don't want to wait you could refactor your code to use the run method:
for($i = 0; $i < 10; $i++) {
$process = new Process('ls -lsa');
$process->run(function ($type, $buffer) {
if (Process::ERR === $type) {
echo 'ERR > '.$buffer;
} else {
echo 'OUT > '.$buffer;
}
});
$procs[$i] = $proc;
}
How to execute php if condition once time only and didn't check it again, i put if condition in for loop and i want to check it one time only:
<?php
for($x=0;$x<3;$x++){
if($x == $x){
echo "";
}
else{
echo "hidden";
}
}
I need to execute first if one time only in for loop
I need to execute first if one time only in for loop. Well that's not how you do it, you need to compare with a variable and upon success just use break to come out of the loop. Something like:
<?php
$y = 0;
for($x=0; $x<3; $x++){
if($x === $y){
echo "X is Equal to Y";
break;
}
else {echo "hidden";}
}
echo "<br>". "You're outside the loop!";
?>
Set a flag, if flag is true don't execute if condition.
<?php
$flag = 0;
for($x=0;$x<3;$x++) {
if($x == $x && $flag == 0){
echo "";
$flag = 1;
}
else{
echo "hidden";
}
}
I need to write code which meets few conditions:
Is an infinity loop
After 4 forks, goes to sleep for 5 seconds.
When in child process, execute things.
When in parent process, fork again.
When it returns -1, catch exception.
So here's what I've written so far:
while(true) {
for ($i = 1; $i <= 4; ++$i) {
$pid = pcntl_fork();
if($pid == 0){
//execute stuff
} else if ($pid == -1){
//error
} else if($pid > 0) {
//fork again?
}
}
sleep(5);
}
But I feel like this is just plain wrong. Also I have no idea how to fork again in parent. How this should look like?
I am trying to use a pcntl extetntion for PHP to run some methods of my CLI class in a new thread. I wrote a small test method:
private function startProcess($data)
{
$this->log('Start a child process');
$pid = pcntl_fork();
if($pid == -1)
$this->log('Could not fork');
elseif($pid)
pcntl_wait($status);
else {
$this->process($data);
sleep(10);
posix_kill(posix_setsid(), SIGTERM);
}
}
This method is called 10 times. $this->process($data); just prints the data in the console. As i understood it should start 10 processes and print my data, after it exit. But instead i get to wait 10 seconds for each message. Where i'm wrong?
You are waiting for each process to complete immediately after starting it. If you really want to run 10 at a time, don't wait until you started all 10.
for($i = 0; $i < 10; $i++)
startProcess(...);
for($i = 0; $i < 10; $i++)
pcntl_wait($status);
private function startProcess($data)
{
$this->log('Start a child process');
$pid = pcntl_fork();
if($pid == -1)
$this->log('Could not fork');
elseif(!$pid) {
$this->process($data);
sleep(10);
posix_kill(posix_setsid(), SIGTERM);
}
}