ждем 2 дочерних процесса - PullRequest
0 голосов
/ 08 мая 2020

Я пытаюсь написать программу C, в которой основной процесс создает двух дочерних элементов: Ping и Pong. Ping печатает «ping», за которым следует число, а Pong печатает «pong», за которым следует число, результат должен быть таким, как в примере выполнения на Рисунке 1: «

enter image description here

Вот что я пытался сделать:

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

void main(){

//initializing pipes
int td[2];
int td2[2];

pipe(td);
pipe(td2);

int pid=fork();
if(pid){ //in parent process

int pid2=fork();

if(pid2){// still in parent process



//1st time
int number1;
printf("Enter a number: ");
scanf("%d",&number1);

write(td[1],&number1,sizeof(number1));
printf("<>");

write(td2[1],&number1,sizeof(number1));
printf("--");


//2nd time
int number2;
printf("Enter a number: ");
scanf("%d",&number2);

write(td[1],&number2,sizeof(number2));
printf("<>");

write(td2[1],&number2,sizeof(number2));
printf("--");

}
else{// in pong process

int number;

read(td2[0],&number,sizeof(number));
printf("pong%d \n",number);

}


}

else{ //in ping process

int number;

read(td[0],&number,sizeof(number));
printf("ping%d \n",number);

}

}//main end

объяснение: проблема, с которой я столкнулся здесь, заключается в том, что pong печатается перед ping, а родительский процесс не ждет своих дочерних элементов до конца (и некоторые выходные данные печатаются после root / desktop et c ..)

Другая проблема, которую я решил, у меня был метод чтения в родительском процессе, он устранил мою проблему, потому что я знаю, что чтение заставляет программа ожидает, пока что-то не будет записано в канал, но в этом случае у нас есть "запись" в родительском процессе, поэтому родитель не ждет

Я также пытался реализовать ожидание (NULL), но он похоже, не работает.

любое предложение будет очень признательно

1 Ответ

1 голос
/ 08 мая 2020

Похоже, что вы (ваш инструктор) слишком усложняете.

Итак, вы хотите, чтобы ваш main() выполнял

int main(void) {
    int n;
    //set up pipes and forks
    printf("Enter a number"); scanf("%d", &n);
    // make child1 output " ping<n>\n"
    puts(" <>");
    // make child2 output " pong<n>\n"
    printf(" --\nEnter a second number"); scanf("%d", &n);
    // make child1 output " ping<n>\n"
    puts(" <>");
    // make child2 output " pong<n>\n"
    puts(" -- THE END --");
    // close pipes
    return 0;
}

Итак, кроме "ping" vs "pong" (и используя разные трубы) дети абсолютно идентичны. Может быть, мы можем послать строку с номером и уменьшить количество функций? Нет ... а как насчет установки строки при создании процесса? Это звучит лучше

// set up pipes and forks
int pipes1[2], pipes2[2];
pipe(pipes1);
if (fork() == 0) /* child #1 */ child("ping", pipes1);
close(pipes1[0]); // the read end of the pipe belongs to the child
pipe(pipes2);
if (fork() == 0) /* child #2 */ child("pong", pipes2);
close(pipes2[0]); // we are not using the read end of the pipe

Теперь ... как нам заставить ребенка (дети ждут своего read() звонка) работать ? Ну просто! Мы пишем на нашем конце канала

scanf("%d", &n); // get value from user
write(pipes1[1], &n, sizeof n); // automatically unblock child1
write(pipes2[1], &n, sizeof n); // automatically unblock child2

Повторите эти инструкции для второго пользовательского ввода.

Не забудьте закрыть концы записи каналов

close(pipes1[1]);
close(pipes2[1]);

И это функция main(). А как насчет функции для детей? child(char *sign, int pipes[2])?

void child(char *sign, int pipes[2]) {
    close(pipes[1]); // close write end
    int i;
    for (;;) {
        if (read(pipes[0], &i, sizeof i)) {
            printf(" %s%d\n", sign, i); // print and go back to waiting at the read()
        } else {
            break; // exit the loop when read fails
        }
    }
    close(pipes[0]); // no more reading
    exit(EXIT_SUCCESS); // not going back to main()
}
...