• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1842
  • Last Modified:

PHP fork child process blocks parent process

I am trying to use PHP fork abilities to run some database queries in the background (triggered by visiting a  web page) but when the fork happens the parent process does not exit until the child is finished causing the browser to appear as if the page has not finished loading.

I am running the script as cgi so it runs using the CLI version of PHP. There are no errors reported. My guess is that the child maintains connection to STDOUT causing the problem.

Here is code that reproduces my problem. Notice the web page will act like it is loading for about 11 seconds.

#!/usr/bin/php
<?PHP
$parentPID = posix_getpid();
declare(ticks=1);
echo "Contact-Type: text/html\n\n";


$pid = pcntl_fork();
if ($pid == -1){
      die("could not fork");
}
else if ($pid){
      exit(); // we are the parent
}
else{
      // we are the child
      $childPID = posix_getpid();
}

// detatch from the controlling terminal
if (posix_setsid() == -1){
      die("could not detach from terminal");
}

echo "MyPID: ".posix_getpid(); // this is sent to the browser, but we should be the child...

if(!posix_kill($parentPID, SIGTERM)){
      // I tried this but it does not help
      die("could not kill parent");
}


// setup signal handlers
pcntl_signal(SIGTERM, "sig_handler");
pcntl_signal(SIGHUP, "sig_handler");

sleep(10); // this simulates the custom code I will use

function sig_handler($signo){
      switch ($signo) {
            case SIGTERM:
                  // handle shutdown tasks
                  exit;
                  break;
            case SIGHUP:
                  // handle restart tasks
                  break;
            default:
                  // handle all other signals
      }
}

?>
0
terabit_ca
Asked:
terabit_ca
1 Solution
 
hernst42Commented:
Thats the way forks work in php. The parent process will end after the child has finished. Better use exec to start a new process. See http://www.php.net/manual/en/function.exec.php :

Note: If you start a program using this function and want to leave it running in the background, you have to make sure that the output of that program is redirected to a file or some other output stream or else PHP will hang until the execution of the program ends.


exec('foo & 1>/dev/null');
0
 
nitinsawhneyCommented:
Generally not all commands could be executed using exec.
The server imposes restrictions to what type of commands are fired from web.

My idea would be to show a message showing something like "Processing Request" when we fork the child and after child finishes show "Processed the request".

Forking only helps in overcoming the timeout problem with heavy queries.

Another way would be that you set the <form target="_blank"> so that when the process starts it starts in a new window, in this way user will still be able to browse other parts of the website.

Cheers!
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now