Как получить статус дочернего процесса от родителя, т. е. он остановлен, продолжен или завершен? Для Linux, язык С

Это программа на языке C в Linux (ubuntu). Я пытался выяснить, как получить статус дочернего процесса от родителя.

Я написал простой дочерний процесс, который считает до 25 за 25 секунд и выводит количество тактов на стандартный вывод. В родительском процессе я 1› останавливаю дочерний процесс на пару секунд. 2› продолжить на пару секунд, а затем 3› убить дочерний процесс. Я хочу получить статус дочернего процесса, для которого я использовал функцию waitpid(). Однако я обнаружил, что если бы я использовал флаги:

waitCondition = WUNTRACED | WПРОДОЛЖЕНИЕ

он возвращает состояние остановки, но зависает, когда находится в состоянии продолжения.

И наоборот, если я установлю флаги на:

waitCondition= WUNTRACED | ПРОДОЛЖЕНИЕ | НИЧЕГО

Статус остановки не регистрируется, но статус продолжения регистрируется функцией waitpid().

Я пытаюсь заставить родительский элемент распознавать состояние остановки, продолжения или выхода.

У меня есть код ниже. У кого-нибудь есть идеи на этот счет? Спасибо!

int waiting4pid()(pid_t processID)
{   
    int waitCondition = WUNTRACED | WCONTINUED;
    int currentState;

    while (waitpid(processID,&currentState,waitCondition) > 0){

        if(WIFCONTINUED(currentState)){
            printf("\n currentState = continued!\n");
        }
        if(WIFSIGNALED(currentState)){
            printf("\n currentState = signaled!\n");            
        }
        if(WIFSTOPPED(currentState)){
            printf("\n currentState = stopped!\n");
        }
        
    }
}

void sigTest()
{ 
    pid_t processID;

    processID = fork();
    if(processID ==0) { // child
       // tmp/loop is an application that counts to 25 in 25 seconds and then exits.
       execlp("tmp/loop", "tmp/loop", NULL);
    }else{ 
        sleep(2);
        printf("\n Stop!");
        kill(processID, SIGSTOP);
        waiting4pid()(processID);
        
        sleep(2);
        printf("\n Continue!");      
        kill(processID,SIGCONT);
        waiting4pid()(processID);
        
        sleep(2);
        printf("\n Kill!"); 
        kill(processID, SIGKILL);
        waiting4pid()(processID);
    }
}

void main() 
{    
    sigTest();
}

person John Alway    schedule 12.04.2021    source источник
comment
Как вы ожидаете, что функция waitpidstatus выйдет из цикла while? Вы отправляете сигнал ребенку, затем вызываете waitpidstatus. Затем waitpidstatus зафиксирует изменение состояния и вернется к ожиданию следующего изменения состояния. Но следующего изменения состояния не будет, поскольку родитель теперь заблокирован на waitpidstatus, поэтому он не может отправить следующий сигнал.   -  person kaylum    schedule 12.04.2021
comment
@kaylum Спасибо! У меня было неправильное представление о том, как работает waitpid().   -  person John Alway    schedule 12.04.2021


Ответы (1)


Чтобы проверить, завершился ли процесс, выполните:

if(WIFEXITED(status) {

    // do your stuff

    // you can also check the exit status
    if(WEXITSTATUS(status) != EXIT_SUCCESS) {
        // the child process exited with error
    }
}

Как уже упоминалось @kaylum в комментарии к вопросу, вызов waitpid() блокируется до тех пор, пока дочерний элемент не изменит состояние. Но вы можете изменить это поведение, вызвав waitpid() с установленным флагом WNOHANG (это было бы полезно, если вам нужно контролировать дочерний процесс, но в то же время выполнять некоторые другие действия в родительском; в качестве альтернативы вы можете waitpid() в отдельном потоке).

person Tomek    schedule 12.04.2021