Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: pcntl_waitpid
Форумы портала PHP.SU » » Операционная система и системные вызовы » pcntl_waitpid

Страниц (1): [1]
 

1. Elio - 08 Июня, 2011 - 15:25:54 - перейти к сообщению
Добрый день!
Возникла у меня ситуация когда нужно воспользоваться pcntl_fork().
Мучаюсь уже 2е сутки.
Еле разобрался с образованием процессов и в каких условиях кто и что выводит на экран.
В общем суть: пользователь нажимает ссылку. Запускается скрипт... в середине скрипт форкается, дитя отдаёт пользователю в брузер "Обновление баз запущенно". А родитель подождав ответа ребёнка об успешном завершении. Идёт дальше собственноручно обновлять базу. (логика была упрощена и сокращенна)
Не получается: родитель не видит завершения дитя... и в процессах висят и ребёнок (хотя уже выполнил скрипт) и родитель со статусом "wait".

и так у меня есть:
PHP:
скопировать код в буфер обмена
  1. //.....some script
  2. switch ($pid = pcntl_fork()) { //форкаем процесс       
  3.         case -1: //если не получилось сфоркать
  4.                 $this->message.='Не удалось создать дочерний процесс.<br/>';
  5.                 return false;
  6.                 break; // кстати надо ли писать break, если до него было использованно return?
  7.        
  8.         case 0: //это выполняет дочерний процесс. собственно выводит сообщение, и должен умереть.
  9.                 $this->message.='Обновление баз запущенно! '.getmypid(); //для debug вывожу pid тк. сам он не умирает и его приходится килять.
  10.                 exit(); // exit должен был выполняться в функции, куда будет возвращено return. для теста был помещён тут.
  11.                 return true;
  12. }
  13. unlink('dump.txt'); //через dump я слушаю что "происходит" с родителем.
  14. $pid = pcntl_waitpid($pid, $status, WUNTRACED); //тут родитель ждёт завершения ребёнка.
  15. file_put_contents('dump.txt', $status.' '.$pid); //записываем статус и полученный ppid ребёнка(получаем для уверенности, что именно дождались ответа ребёнка)

после выполнения оба процесса висят в "ps" и убиваются только kill. текст пользователь видит и у него страница полностью загружена (те ребёнок отработал). Не пойму как сообщить матери, что можно "убивать дитё" и работать дальше.

Заранее благодарен.
2. DeepVarvar - 08 Июня, 2011 - 19:39:14 - перейти к сообщению
PHP:
скопировать код в буфер обмена
  1. $childs = array();
  2. $pid = pcntl_fork();
  3. if ($pid == -1) { echo "child process create error...\n"; }
  4. elseif ($pid) { $childs[$pid] = true; } // мамка
  5. else {
  6.     // дитя только в этой ветке
  7.     echo "starting child $pid..\n";
  8.     long_work_function();
  9.     }
  10. // мамка смотрит за детками
  11. while (true) {
  12.     while ($signal = pcntl_waitpid(-1,$status,WNOHANG)) {
  13.         if ($signal == -1) { // все подохли
  14.             $childs = array();
  15.             break 2; // завершаемся сами
  16.             }
  17.         else unset($childs[$signal]); // дитя хочет сдохнуть
  18.         }
  19.     sleep(3); // шоб не жрало ресурсы
  20.     }


Кстати расскажите ка нам КАК вы запускаете эти ф-ции в CGI-режиме???
3. Elio - 09 Июня, 2011 - 10:56:01 - перейти к сообщению
Прошу прощение за свою не осведомлённость...
Это у меня обычный PHP файл/скрипт. Запускается пользователем зайдя на страницу index.php
Вы хотите сказать, что для работы с процессами я должен превратить php в cgi-скрипт?
Просто я плохо представляю себе саму сущность CGI, и только пару раз встречал этот термин в интернете.
4. DeepVarvar - 09 Июня, 2011 - 12:03:47 - перейти к сообщению
Elio пишет:
Запускается пользователем зайдя на страницу index.php
значит CGI.

Так вот "pcntl_fork() и Компания" не работают в CGI-режиме, только в CLI.
Вполне ожидаемый вопрос: КАК он работает у вас?
5. Elio - 09 Июня, 2011 - 14:49:35 - перейти к сообщению
DeepVarvar пишет:
Так вот "pcntl_fork() и Компания" не работают в CGI-режиме, только в CLI.

На сколько я понимаю значение слова "не работает" это когда функция, либо вообще не запускается, либо вываливается с ошибкой.
Но беда в том, что pcntl_fork() создаёт таки дубликат процесса, и ppid у него присваивается родительский, а родитель, если не ставить pcntl_waitpid() продолжает и дальше выполнять свои функции.
Проблема только с sql соединением. Тк когда один из клонов завершает своё "выполнение", соединение закрывается для обоих, но эта проблема понятна и решаема, собственно как и вывод информации на экран. (кто первый, того и тапки)
Но мне именно надо отслеживать действия или бездействия Родителем. Может даже с помощью сигналов.
И если "внешний" вызов скрипта это cgi режим. То почему работает Форк? 0_о
PS. не подскажите ещё как запустить его в cli режиме? (Догадываюсь, что только через серверную консоль. Или же всёже можно через exec()?)
6. DeepVarvar - 09 Июня, 2011 - 23:58:12 - перейти к сообщению
Можно и через "обертку" exec(), а можно и в консоли, синтаксис для обоих одинаков:
[путь до интерпретатора] [путь до файла, и аргументы опционально]

в нашем случае без аргументов:

$ /usr/bin/php /path/do/script.php

Elio пишет:
значение слова "не работает" это когда функция, либо вообще не запускается, либо вываливается с ошибкой.
именно так..
Elio пишет:
отслеживать действия или бездействия Родителем
а вы мой пример пробовали???

Elio пишет:
То почему работает Форк? 0_о
хз, но так не должно быть.
Вы пхп сами собирали или из репов ставили???...

 

Powered by ExBB FM 1.0 RC1