Paulo Rodrigues
Paulo Rodrigues

Reputation: 613

PHP fork unexpected behaviour: Parent process waits till the child process exits

I have a php script that displays a web form to the user. When the user submits the form, i save the data in the database and then i fork a process, the son, to send some SMS to the database users afected with the new changes.

When i fork, i check for the son, and he sends the SMS correctly, and in the end exits. But by some reason, the father waits for the son to do his tasks. I dunno why this is happening..

Here is a sample of my code:

    // before this point, i've inserted some data in the database, and now i commit the transaction
    $conn->commit();
    $pid = pcntl_fork();
if ($pid == 0) {    // its the son, so he will send the messages
  $conn = new PDO('oci:dbname='.SERVER.';charset='.CHARSET, DATABASE, PASSWORD);
  $suppliersPhoneNumber = getSuppliersPhoneNumber($conn, ...);
  $conn = null;
  $sms = new MessageSender($suppliersPhoneNumber, $_POST['subCategory']);
  $sms->handleMessages();   // send the sms     
      //sleep(60);      
  exit(0);  // the son won't execute more code
}/

The line with the code "sleep(60)" is how i know that the father is waiting for the child. But how is this possible if the son exits?? I know the father waits for the son, cause in fact my script freezes for 1 minute, the waiting time.

My idea is to have a father inserting the required data in the database, in the end he spawns a new child to send the messages, but doesn't waits for him, so we can send a response page to the user saying everything went fine, while the messages are effectively being sent.

What is going wrong here?

Thks in advance

EDIT The problem was not solve, instead i followed the solution of Paulo H. registed below. Indeed it was a better way.

Upvotes: 1

Views: 3052

Answers (3)

noobie-php
noobie-php

Reputation: 7223

instead of

 exit();

try using this

posix_kill(getmypid(),9);

and please tell if this works.

Upvotes: 0

SlappyTheFish
SlappyTheFish

Reputation: 2384

By forking a process the child process will be in the same process group. Perhaps Apache, or whatever web server you are using is waiting for all processes in the group to end before detaching and ending the request.

Try calling setsid() in the child after forking which should put it as a leader in a new group.

http://www.php.net/manual/en/function.posix-setsid.php

Upvotes: 0

Paulo H.
Paulo H.

Reputation: 1258

I believe that you are using Apache to run this code, I suggest you run a completely separate process in the background.

I think the problem is happening because Apache waits for this child process before sending the information to the browser. Anyway do not recommend fork if not in a php-cli script.

Usually the child process stay in zombie mode until the parent process call a "wait", but there not seems to be the case.

Upvotes: 1

Related Questions