2009-12-30 2 views
2

Я получаю неправильный код выхода от waitpid, и я не могу понять, почему. Может ли кто-нибудь дать мне некоторые идеи?Почему waitpid в Perl возвращает неверный код выхода?

Вот что я делаю:

  1. Я начинаю свой дочерний процесс с open2
  2. тогда я ждать его, чтобы закончить с waitpid
  3. получить код выхода, используя $?

Это всегда возвращает с -1 no mater, что я возвращаюсь из дочернего процесса. Я проверяю с VS отладчик, что моя программа возвращает код выхода 0. VS говорит что-то вроде этого:

The program '[3256] Test.exe: Native' has exited with code 0 (0x0). 

Я убедился, что ИДП матч.

Любые идеи?

+2

Не могли бы вы опубликовать свой код Perl, используя "сон" вместо вашей программы? – Arkadiy

ответ

7

Я только что понял. waitpid имеет 3 этапа:

1. process is running: waitpid returns 0; $? is -1 
2. process is exiting: waitpid returns pid; $? is actual exit code 
3. process doesn't exist: waitpid returns -1; $? is -1 

так, когда что-то делать, как-то время (waitpid ($ Pid, ​​WNOHANG)> = 0) код выхода должен быть извлеченной раз цикла до этого.

+1

Или вы можете просто вызвать waitpid ($ pid, 0), и он будет ждать, пока программа не выйдет. –

+0

Ah - yes waitpid только сообщает результат один раз. –

+0

Paul: да, это сработает, но я не могу это заблокировать, потому что мне нужно читать файлы журналов во время работы. –

3

От waitpid man page:

Обратите внимание, что на некоторых системах, возвращаемое значение «-1» может означать , что в настоящее время автоматически пожинали дочерние процессы. См. perlipc для получения более подробной информации и других примеров.

0

Вместо использования waitpid вы должны просто закрыть дескриптор файла. (Я предполагаю, что «open2» в вашем вопросе - опечатка, и вы имели в виду «открытый»)

+4

open2 (см. IPC :: Open2) - это вызов, который позволяет отправлять и получать выходные данные из одной и той же программы. – mob

0

работает для меня (Windows):

use IPC::Open3; 
use POSIX ':sys_wait_h'; 
use Time::HiRes; 

$|++; 

my ($fin, $fh, $pid); 
$pid = open3($fin, $fh, 0, 'ping', '8.8.8.8') or die('error'); 

my @lines =(); 
while (1) { 
    while (my $line = <$fh>) { 
     push(@lines, $line); 
     print('+'); 
    } 
    print("\nret: `$?`\n"), last if waitpid($pid, WNOHANG) <= 0; 
    Time::HiRes::usleep(100000); 
    $fh->clearerr(); 
} 
waitpid($pid, 0); 
print("\nret: `$?`\n"); 

Выведет:

++++++++++++ 
ret: `-1` 

ret: `0`