PHP fork意外行为:父进程等待子进程退出

时间:2011-12-07 12:00:08

标签: php process fork

我有一个PHP脚本,向用户显示Web表单。当用户提交表单时,我将数据保存在数据库中,然后我分叉一个进程,儿子,向一些用新的更改感染的数据库用户发送一些短信。

当我叉,我检查儿子,他正确发送短信,最后退出。 但由于某种原因,父亲等待儿子完成他的任务。我不知道为什么会发生这种情况..

以下是我的代码示例:

    // 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.确实这是一种更好的方式。

3 个答案:

答案 0 :(得分:1)

我相信您正在使用Apache运行此代码,我建议您完全运行separate process in the background

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

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

答案 1 :(得分:0)

通过分配进程,子进程将位于同一进程组中。也许Apache或您使用的任何Web服务器都在等待分组中的所有进程在分离和结束请求之前结束。

在分叉之后尝试在子代中调用setsid(),这应该将它作为新组中的领导者。

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

答案 2 :(得分:0)

而不是

 exit();

尝试使用此

posix_kill(getmypid(),9);

请告诉我这是否有效。