Как родительский процесс получает статус завершения через ожидание от дочернего процесса, который вызывает _exit - PullRequest
2 голосов
/ 19 июля 2011

Я прочитал следующее утверждение.

Аргумент состояния, данный _exit (), определяет статус завершения процесс, который доступен родителю этого процесса, когда он ожидание звонков ().

Процесс всегда успешно завершается с помощью _exit () (т. Е. _exit () никогда не возвращается ).

Вопрос

Если _ exit не возвращается, как родительский процесс может получить статус завершения от дочернего процесса через wait ?

Ответы [ 4 ]

3 голосов
/ 19 июля 2011

Когда дочерний процесс завершается, ядро ​​хранит некоторую информацию об этом.К этой информации относится код возврата.

Между тем родитель не завершен.Позвонив по номеру wait или waitpid, он просто спрашивает ядро: «Эй, ты знаешь моего ребенка? Каков его статус?».

2 голосов
/ 19 июля 2011

Всякий раз, когда происходит выход из процесса (независимо от того, вызывается ли он _exit (int Exit_Status)), ядро ​​отправляет функцию SIGCHLD своему родителю.родитель может либо

     1. Ignore the incoming signal
     2. Catch it by installing a signal handler

В частности, родитель может поймать состояние выхода, вызвав функцию wait () или waitpid ().В этом случае LSB делается доступным для родителя.В частности, статус может быть изучен следующим образом:

    int status;
    wpid = waitpid(child_pid, &status, WUNTRACED);

Поскольку доступны только последние 8 битов, будет логично замаскировать старший бит, выполнив битовую операцию и операцию с 255. Определенный системой макрос делает это дляyou

   WEXITSTATUS(status);

Таким образом, чтобы получить дочерний статус - вы можете использовать после оператора waitpid

   printf("child exited, status=%d\n", WEXITSTATUS(status));

Игнорирование SIGCHLD может привести к созданию процесса зомби (несуществующего)).Установка флага SA_NOCLDWAIT для SIGCHLD не создает зомби, поскольку ядро ​​их пожинает.Однако код не переносим, ​​и лучше использовать системный вызов wait.

2 голосов
/ 19 июля 2011

Внутри функции _exit (int status) процесс уведомляет родительский процесс через SIGCHLD о том, что он собирается завершиться, и младшие 8 бит состояния становятся доступными для родительского процесса.Существует три способа обработки состояния выхода

  1. Родительский процесс может указывать, что он не заинтересован в возвращаемом значении, и в этом случае состояние выхода отменяется, а дочерний процесс завершается.
  2. Родительский процесс может находиться в ожидании (), затем статус сообщается родителю, и дочерний процесс завершается.
  3. Родительский процесс не находится в wait (), затем дочерний процесспроцесс превращается в процесс зомби, цель которого состоит в том, чтобы ждать, пока родительский объект сделает вызов wait (), чтобы получить статус выхода.
1 голос
/ 19 июля 2011

_exit() не возвращается означает, что когда процесс вызывает _exit(), этот вызов никогда не возвращается (в данном случае, потому что процесс завершается).

_exit() - системный вызови принимает аргумент.Ядро сохраняет этот аргумент во внутренней структуре.Ядро имеет упрощенную структуру для процессов, которые уже вышли, но еще не ожидали (зомби).Когда процесс ожидает своих потомков с помощью wait() (еще один системный вызов), ядро ​​получает это значение и забывает о зомби.

...