2016-10-06 1 views
-1

Обучающая ОС обычно рассматривается в любых учебниках, в которых используется fork() в родительском процессе для создания дочернего процесса и иногда вызывает wait() в родительском объекте, чтобы дождаться завершение ребенка.ОС: wait() в дочернем процессе

Но что происходит, если я использую wait() в дочернем?

#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <sys/wait.h> 

int 
main(int argc, char** argv){ 
    int x; 
    int w1, w2; 
    x = 100; 
    printf("the initialized x is: %d\n",x); 
    int rc = fork(); 
    if(rc < 0){ 
    fprintf(stderr, "fork failed.\n"); 
    exit(1); 
    } 
    else if(rc == 0){ 
    //x = 200;                 
    w1 = wait(NULL); 
    printf("the x in child process (pid:%d) is: %d\n", (int) getpid(), x); 
    } else { 
    x = 300; 
    w2 = wait(NULL); 
    printf("the x in parent process (pid:%d) is: %d\n",(int) getpid(), x); 
    } 
    printf("the x in the end is: %d\n",x); 
    printf("the returns of waits: %d, %d\n",w1,w2); 
    return 0; 
} 

Этот кусок кода прогонов и показывает следующее:

dhcp175:hw_ch5 Suimaru$ ./a.out 
the initialized x is: 100 
the x in child process (pid:18844) is: 100 
the x in the end is: 100 
the returns of waits: -1, 0 
the x in parent process (pid:18843) is: 300 
the x in the end is: 300 
the returns of waits: 0, 18844 

Как это объяснить?

ответ

2

Но, что произойдет, если я использую wait() для ребенка?

Вы прочитали личную информацию? Особенно детали о возвращаемом значении и условиях ошибки? Я вижу, что вы провели эксперимент, и это хорошо; между этим и документами, уже должно быть ясно, что если процесс, вызывающий wait(), не имеет дочерних процессов для ожидания, то он немедленно возвращает -1, указывая на ошибку. В этом случае errno будет установлен в ECHILD.

И возврат немедленно с ошибкой имеет смысл, поскольку единственная альтернатива, если вызывающий процесс не имеет детей, - это ждать, возможно, бесконечно, для события, которое не может произойти до тех пор, пока оно ждет.

0

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

#include <unistd.h> 
#include <sys/wait.h> 
#include <sys/types.h> 
#include <errno.h> 
#include <stdio.h> 
#include <string.h> 

... 

char err_msg[4096]; // a buffer big enough to hold an error message 
errno = 0; // clear errno just in case there was an earlier error 
pid_t fpid = fork(); 
if (fpid < 0) 
{ 
    perror("fork failed.\n"); // prints out an error string based on errno 
    exit(1); 
} else if (fpid == 0) 
{ // in child 
    pid_t wpid = wait(NULL);                
    strerror_r(errno, err_msg, sizeof(err_msg)); // gets an error string 
    printf("child process (pid:%d), wpid:%d, %s\n", (int) getpid(), (int)wpid, err_msg); 
} else { 
    int err_val; 
    wpid = wait(NULL); 
    err_val = errno; 
    errno = 0; // reset errno 
    strerror_r(err_val , err_msg, sizeof(err_msg)); // gets an error string 
    printf("parent process (pid:%d), wpid:%d, %s\n", (int) getpid(), (int)wpid, err_msg); 
    if (err_val != 0) 
    { 
     // there was an error, so what are you going to do about it? 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^