Неожиданное поведение форка PHP: родительский процесс ожидает завершения дочернего процесса - PullRequest
1 голос
/ 07 декабря 2011

У меня есть скрипт php, который отображает веб-форму для пользователя.Когда пользователь отправляет форму, я сохраняю данные в базе данных, а затем раскладываю процесс, сын, чтобы отправить SMS-сообщение пользователям базы данных, затронутым новыми изменениями.для сына, и он отправляет смс правильно, и в конце концов выходит.Но по какой-то причине отец ждет, пока сын выполнит его задачи.Я не знаю, почему это происходит ..

Вот пример моего кода:

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

Строка с кодом «сон (60)», как я знаю, что отецжду ребенка.Но как это возможно, если сын выходит ??Я знаю, что отец ждет сына, потому что на самом деле мой сценарий останавливается на 1 минуту, время ожидания.

Моя идея состоит в том, чтобы отец вставил необходимые данные в базу данных, в конце он порождаетновый ребенок отправляет сообщения, но не ждет его, поэтому мы можем отправить пользователю страницу ответа, в которой говорится, что все прошло нормально, пока сообщения эффективно отправляются.

Что здесь не так?

Заранее спасибо

РЕДАКТИРОВАТЬ Проблема не была решена, вместо этого я следовал решению Пауло Х., указанному ниже.На самом деле это был лучший способ.

Ответы [ 3 ]

1 голос
/ 07 декабря 2011

Я полагаю, что вы используете Apache для запуска этого кода, я предлагаю вам запустить отдельный процесс в фоновом режиме .

Я думаю, что проблема происходит, потому что Apache ждет этогодочерний процесс перед отправкой информации в браузер.В любом случае, не рекомендуется использовать fork, если не в скрипте php-cli.

Обычно дочерний процесс остается в режиме зомби, пока родительский процесс не вызовет « wait », но, похоже, чтодело.

0 голосов
/ 07 декабря 2011

вместо

 exit();

попробуйте использовать это

posix_kill(getmypid(),9);

и, пожалуйста, сообщите, если это работает.

0 голосов
/ 07 декабря 2011

При разветвлении процесса дочерний процесс будет находиться в той же группе процессов.Возможно, Apache или любой используемый вами веб-сервер ожидает завершения всех процессов в группе, прежде чем отсоединять и завершать запрос.

Попробуйте вызвать setsid () у дочернего элемента после разветвления, который должен поставить его в качестве лидера.в новой группе.

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

...