Возвращение из exit () с помощью fork () странно - PullRequest
0 голосов
/ 28 октября 2018

У меня есть код на C, который иногда сам себя разветвляет, каждая вилка что-то делает, а затем возвращает код ошибки. В настоящее время каждый дочерний процесс возвращает свой идентификатор (0..n).

void other(int numero){
    ...
    exit(numero);
}

int main(...){
    for(int i = 0; i < 6; i++){
        if(fork() == 0){
            other(i);
        }
    }
    int order[6];
    for(int i = 0; i < 6; i++){
        int code;
        waitpid(0, &code, 0);
        order[i] = code; // <-- HERE
    }
}

Странно, это возвращает кратное реального значения. Заменив строку, я пометил:

order[i] = code >> 8;

Мне удалось получить ожидаемый результат 0..5. Однако я действительно не понимаю, почему это происходит. Я ожидаю, что это из-за какой-то проблемы с типом, но я не вижу этого, я всегда использую целые числа.

Ответы [ 2 ]

0 голосов
/ 28 октября 2018

Вы должны использовать макросы W* из sys/wait.h для интерпретации состояний выхода.

См. Справочную страницу waitpid .

Что касается необработанного значения, вы можете рассчитывать только на тот факт, что status==0 означает WIFEXITED(status) && WEXITSTATUS(status)==0 (см. http://pubs.opengroup.org/onlinepubs/9699919799/functions/waitpid.html, который описывает эту специальную гарантию).

0 голосов
/ 28 октября 2018

Правильная замена для order[i] = code; - order[i] = WEXITSTATUS(code); Также обратите внимание, что waitpid может вернуться, даже если процесс не завершился;Вы должны использовать WIFEXITED, чтобы убедиться, что это так.

С man 2 waitpid:

   If wstatus is not NULL, wait() and waitpid() store status information
   in the int to which it points.  This integer can be inspected with
   the following macros (which take the integer itself as an argument,
   not a pointer to it, as is done in wait() and waitpid()!):

    WEXITSTATUS(wstatus)
          returns the exit status of the child.  This consists of the
          least significant 8 bits of the status argument that the child
          specified in a call to exit(3) or _exit(2) or as the argument
          for a return statement in main().  This macro should be
          employed only if WIFEXITED returned true.

Вы должны использовать различные перечисленные здесь макросы,например, WEXITSTATUS в вашем случае, чтобы иметь смысл wstatus.Кроме их использования, wstatus можно рассматривать только как непрозрачный блоб (кроме особого случая, когда он равен 0).

...