Я написал простую C-программу в RedHat Linux, которая ждет дочернего процесса, использующего waitpid после вызова execv.
int main( int argc, char * argv[] )
{
int pid;
int status = 0;
int wait_ret;
const char * process_path = argv[1];
if ( argc < 2 )
{
exit( EXIT_FAILURE );
}
pid = fork(); //spawn child process
if ( 0 == pid ) //child
{
int ret = execv( process_path, &argv[1] );
if ( ret )
{
printf( "execv failed: %s\n", strerror( errno ) );
}
exit( EXIT_SUCCESS );
}
//wait for the child to terminate
wait_ret = waitpid( pid, &status, WUNTRACED );
if ( -1 == wait_ret )
{
printf( "ERROR: Failed to wait for process termination\n" );
exit( EXIT_FAILURE );
}
// ... handlers for child exit status ...
return 0;
}
Я использую это как простой сторож для некоторых процессов, которые я запускаю.
Моя проблема в том, что один процесс, в частности, не вызывается waitpid при выходе и вместо этого остается навсегда в состоянии Zombie, пока waitpid зависает.Я не уверен, почему waitpid не может пожинать этот процесс, когда он становится зомби (может быть, дескриптор пропущенного файла или что-то в этом роде).
Я мог бы использовать флаг WNOHANG и опрашивать дочерний файл proc stat для проверкиЗомби, но я бы предпочел более элегантное решение.Может быть, есть какая-нибудь функция, которую я мог бы использовать, чтобы получить статус Zombie, не опрашивая этот файл?
Кто-нибудь знает альтернативу waitpid, которая вернется, когда процесс станет зомби?
ДополнительноИнформация:
Дочерний процесс закрывается вызовом exit( EXIT_FAILURE);
в одном из его потоков.
cat /proc/<CHILD_PID>/stat
(до выхода):
1037 (my_program) S 1035 58 58 0 -1 4194560 1309 0 22 0 445 1749 0 0 20 0 13 0 4399 22347776 1136 4294967295 3336716288 3338455332 3472776112 3472775232 3335760920 0 0 4 31850 4294967295 0 0 17 0 0 0 26 0 0 333848 038 038 338 038 038 338 4830 33
cat /proc/<CHILD_PID>/stat
(после выхода):
1037 (my_program) Z 1035 58 58 0 -1 4227340 1316 0 22 0 464 1834 0 0 20 0 2 0 4399 0 0 4294967295 0 0 0 0 0 00 0 4 31850 4294967295 0 0 17 0 0 0 26 0 0 0 0 0
Обратите внимание, что дочерний PID равен 1037, а родительский PID - 1035 в этом случае.