Проблема с процессам pcntl

skeeper

Guest
Проблема с процессам pcntl

Перепробовал все что только можно, код уже искорежил до безумия, но все равно процессы плодятся и не убиваются =((
Точнее <defunct> - может так и надо, но мне кажется что это не правильно. Подскажите плз. где грабли
PHP:
function RunProcess() {
global $child,$max
for ($i = 1; $i <= 10; $i++) {
 while ($child >= $max) {
  }
  $child++;
  $pid=pcntl_fork();
  if ($pid == -1) {
   die("could not fork");
  } elseif ($pid) {
  $fl = fopen ('./pids', "a");flock($fl, LOCK_EX);fputs ($fl, $pid."\n");flock($fl, LOCK_UN);fclose ($fl);
  } else {
       DownloadPage();
       exit;
  }
}
function sig_handler($signo) {
  global $child;
  switch ($signo) {
   case SIGCHLD:
     $child -= 1;
  }
}

declare(ticks = 1);

pcntl_signal(SIGCHLD, "sig_handler");

$max=10;
for ($i = 1; $i <= 10; $i++) {
 $child=0;
 RunProcess();
 $lines = file ('./pids');
 foreach ($lines as $line_num => $line) { 
  $line = trim($line);
  posix_kill($line, SIGTERM);
 } 
  // ВОТ КОГДА $i =2 и больше ps -A показывает порядка 
  // 10  строчек 
 // pts/0  00:00:00  php 
 // и очень много строчек  
 // 4448 ?        00:00:00 php <defunct>
// Когда эту прогу тушишь Ctrl-c то все процессы медленно исчезают
}
 

Tor

Новичок
непонятно
ты процессу посылаешь SIGTERM
обработчик у тебя только на SIGCHLD, причем не ясно, что он делает
 

skeeper

Guest
так SIGCHLD это для работы с детьми.
а на сколько я понял posix_kill($line, SIGTERM);
должен просто процесс убивать и все.

Скажу честно, я в процессах 2ой день только разбираюсь и еще не до конца осознаю как это работает =)
 

Tor

Новичок
дочерний процесс выполняет свою задачу и делает exit;
парент ждет его по pcntl_waitpid
все просто
 

skeeper

Guest
Пытался делать
PHP:
} elseif ($pid) { 
 pcntl_waitpid($pid, $tmpstat, 0); // terminate kid for real.
}
Не помогает php <defunct> не убиваются.
 

skeeper

Guest
Тогда все пролетит моментально и процессы умрут сами по себе потому что скрипт закончит работу
 

Tor

Новичок
значит проблема не в pcntl
а в том, что DownloadPage() работает и работает
и до exit; дело не доходит
 

skeeper

Guest
Судя по результатам работы программы DownloadPage() работает нормально. Во всяком случае скачивает и ровно столько сколько циклов.
Т.е. этот код рабочий - и работает замечательно. Только зомби меня волнуют, так как память они жрут очень неплохо
=(
т.е. если цикл будет до 10000 а не до 10, то скорее всего сервак ляжет из-за нехватки памяти, так процессы отрабатывают но не удаляются из памяти, т.е. становятся зомби
НО скрипт при этом выполняет все точно и правильно.
 

Tor

Новичок
поставь между DownloadPage() и exit - echo и посмотри, доходит ли до него дело
и еще: DownloadPage() внешние или дочерние процессы запускает ?
 

skeeper

Guest
да. доходит. DownloadPage ничего не запускает.
Там через Curl выкачивается страничка. При этом там стоит таймайут и эта функция ПО ЛЮБОМУ вываливается через 15 секунд
 

Tor

Новичок
т.е. если DownloadPage убрать, то все работает
в нем только curl

я правильно понимаю?
 

Screjet

Новичок
хех, зомби? Угадал?
Убери нафик SIGCHLD и разбирайся с pcntl_wait().
 
Сверху