Функция системного вызова в C - PullRequest
0 голосов
/ 04 февраля 2020

Может кто-нибудь объяснить мне, что делает ожидание и в чем разница между выходом (0), выходом (1), выходом (2) и т. Д.

Вот код, в котором я запутался.

int main() 
{ 
    if (fork()== 0) 
        printf("HC: hello from child\n"); 
    else
    { 
        printf("HP: hello from parent\n"); 
        wait(NULL); 
        printf("CT: child has terminated\n"); 
    } 

    printf("Bye\n"); 
    return 0; 
} 

Выходные данные

HC: hello from child
Bye
HP: hello from parent
CT: child has terminated
     (or)
HP: hello from parent
HC: hello from child
CT: child has terminated    // this sentence does 
                            // not print before HC 
                            // because of wait.
Bye

это код от geeksforgeeks, поэтому он переходит к оператору if, и если оператор if равен true, тогда он выполняет printf("HC: hello from child\n");, но почему он go возвращается в оператор else и распечатывает printf("HP: hello from parent\n"); printf("CT: child has terminated\n");?

Ответы [ 3 ]

0 голосов
/ 04 февраля 2020

Относительно вашего первого вопроса в заявлении о выходе,

Синтаксис void exit(int status) и указывает, Функция exit(0) используется для указания успешного завершения программы C. Функция exit(1) обычно используется для указания того, что программа не была успешно завершена и управление возвращается в среду хоста с кодом возврата 1 Точно так же любой статус , который может не быть 0, используется для указания неудачного завершения программы, и это действительно зависит от выбора программиста использовать код выхода.

Относительно вашего второго вопроса на форк заявление,

Когда вы вызвали функцию pid_t = fork(void), она фактически создает дочерний процесс, родительский процесс которого является вызывающим процессом, в котором вызывается fork(). Здесь дочерний процесс является точной копией родительского процесса и продолжает его выполнение с момента вызова fork(). В случае успеха PID ( ID процесса ) дочернего процесса возвращается в родительский, а 0 возвращается в дочерний. В случае ошибки -1 возвращается в родительский процесс, дочерний процесс не создается

0 голосов
/ 04 февраля 2020

при вызове fork() будет создан другой процесс. Однако в этом новом процессе он вернет значение «0». Таким образом, процессы после fork будут выполняться одновременно и будут выглядеть следующим образом после расширения оператора if.

новый процесс:

        printf("HC: hello from child\n"); 

    printf("Bye\n"); 
    return 0; 
} 

основной процесс:

int main() 
{ 
          printf("HP: hello from parent\n"); 
        wait(NULL); 
        printf("CT: child has terminated\n"); 

    printf("Bye\n"); 
    return 0; 
} 

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

Как видите, printf "bye" существует и в дочернем процессе, поэтому он будет печатается перед оператором ожидания в основном процессе. тогда основной процесс продолжится с этого момента.

Обычно, когда дочерний объект создается, он должен заканчиваться в том же предложении 'if', поэтому, если вы добавите туда оператор 'return' или 'exit', вы увидите лучший результат:

 if (fork()== 0) {
        printf("HC: hello from child\n");
        exit (0);
    }

В приведенном выше утверждении дочерний элемент завершит работу после того, как напечатает свое сообщение, и никогда не напечатает «пока».

Что касается exit, вызов позволяет вам завершить вашу программу от любой процедуры, которую она выполняет. Его аргумент - это статус, который возвращается из программы в операционную систему. В соглашении unix «0» означает успех. Другие значения представляют код ошибки. Но это все зависит от вас.

0 голосов
/ 04 февраля 2020

Вы смотрите на это с точки зрения одного процесса. fork() создает другой процесс, который является точной копией родительского процесса с только одним отличием: результат вызова функции fork() для клона равен 0, но для родительского элемента это PID результат операции.

Следовательно, if (fork == 0) будет верно только для ребенка.

Другими словами обе ветви следуют одновременно.

Часть wait() - это то, как родительский процесс ожидает завершения дочернего процесса. NULL в качестве аргумента означает примерно "не важно, какой ребенок, только первый, который делает". Обычно вы используете waitpid() со значением pid, полученным из вызова fork(), но это действительно очень важно, если потенциально задействовано несколько дочерних процессов.

Если вы не «пожинаете» ваш дочерний процесс в итоге вы получите зомби , поэтому важна часть wait.

...