PHP fork异常行为:父进程等待子进程退出


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

我有一个php脚本,显示一个web表单给用户。当用户提交表单时,我将数据保存在数据库中,然后我fork一个进程,子进程,向受新更改影响的数据库用户发送一些短信。

当我分叉时,我检查儿子,他正确发送短信,并最终退出。但出于某种原因,父亲等待儿子完成他的任务。我不知道为什么会这样。

下面是我的代码示例:

    // 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
}/

代码"sleep(60)"的行是我如何知道父亲正在等待孩子的。但如果儿子退出,这怎么可能?我知道父亲在等儿子,因为事实上我的剧本冻结了1分钟,等待的时间。

我的想法是有一个父亲插入所需的数据在数据库中,最后他产生一个新的孩子发送消息,但不等待他,所以我们可以发送一个响应页面给用户说一切都很好,而消息是有效地发送。

这里出了什么问题?

提前感谢

编辑这个问题没有解决,而是按照下面注册的Paulo H.的解决方案。

我相信你是用Apache来运行这段代码的,我建议你在后台运行一个完全独立的进程。

我认为问题正在发生,因为Apache在将信息发送到浏览器之前等待此子进程。无论如何,如果不在php-cli脚本中,不建议使用fork。

通常子进程保持僵尸模式直到父进程调用"wait",但似乎没有这种情况。

通过派生一个进程,子进程将在同一个进程组中。也许Apache,或者你正在使用的任何web服务器正在等待组中的所有进程在分离和结束请求之前结束。

尝试在fork后在子组中调用setsid(),这将使它成为新组中的leader。

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

代替

 exit();

尝试使用

posix_kill(getmypid(),9);