понимание fork (), sleep () и процессов flux - PullRequest
4 голосов
/ 17 ноября 2011

Я практиковался с этими системными вызовами, но я застрял в этом коде:

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

main()
{
    pid_t pid;
    switch(pid = fork())
    {
        case -1:
            printf("fork failed");
            break;
        case 0:  //first child
            printf("\ni'm the first child, my pid is %d", getpid());
            fflush(stdout);
            break;
        default:    //parent
            sleep(5); /** sleep is generating problems **/
            printf("\ni'm the parent process, my pid is %d", getpid());
            printf("\ngenerating a new child");
            fflush(stdout);
            switch(pid = fork())
            {
                case -1:
                    printf("fork failed");
                    break;
                case 0: //second child
                    printf("\nhere i am, the second child, my pid is %d", getpid());
                    break;
                default:  //parent
                    wait((int *)0);
                    printf("\nback to parent, my pid is %d", getpid());
            }
    }

    return 0;
}

Вывод, который я получаю:

i'm the first child, my pid is 6203
i'm the parent process, my pid is 6202
generating a new child
back to parent, my pid is 6202
Process returned 0 (0x0)   execution time: 5.004 s
Press ENTER to continue

here i am, the second child, my pid is 6204

То, что я пытаюсь этопростая печать этих сообщений, управляющая временем через sleep().Я не могу понять, почему программа возвращается перед печатью второго дочернего сообщения.Регистр по умолчанию (тот, что сразу после второй ветки) был напечатан до того, как его дочерний элемент (второй) воздействовал на вывод, как если бы он игнорировал его wait().Поэтому его потомок был напечатан после завершения процесса.

Я не смог понять, в чем проблема.Я пометил функцию sleep (), поскольку, если я заменю ее на wait((int *)0);, поток процессов будет работать так, как он был спроектирован (во всяком случае, без какой-либо синхронизации).На данный момент я больше не уверен насчет потока процессов или использования sleep () (справочные страницы были не очень полезны, слишком краткими, чтобы быть честными).

Ответы [ 2 ]

4 голосов
/ 17 ноября 2011

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

Обновлен код теста:

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

main()
{
    pid_t pid;
    int status;
    switch(pid = fork())
    {
        case -1:
            printf("fork failed");
            break;
        case 0:  //first child
            printf("\ni'm the first child, my pid is %d", getpid());
            fflush(stdout);
            break;
        default:    //parent
            sleep(5); /** sleep is generating problems **/
            printf("\ni'm the parent process, my pid is %d", getpid());
            printf("\ngenerating a new child");
            fflush(stdout);
            switch(pid = fork())
            {
                case -1:
                    printf("fork failed");
                    break;
                case 0: //second child
                    printf("\nhere i am, the second child, my pid is %d", getpid());
                    break;
                default:  //parent
                    pid = wait(&status);
                    printf("\nParent detects process %d was done", pid);
                    pid = wait(&status);
                    printf("\nParent detects process %d was done", pid);
                    printf("\nback to parent, my pid is %d", getpid());
            }
    }

    return 0;
}

Выход:

i'm the first child, my pid is 30897
i'm the parent process, my pid is 30896
generating a new child

here i am, the second child, my pid is 30940
Parent detects process 30897 was done
Parent detects process 30940 was done
back to parent, my pid is 30896
1 голос
/ 17 ноября 2011

В справочной странице ожидания указано следующее:

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

Ожидание возвращается из-за первого ребенка.

...