Работая с родительским процессом и двумя дочерними процессами, моя цель состоит в том, чтобы реализовать простой канал, который бы отправлял выходные данные дочернего элемента A на вход дочернего элемента B. Я хотел, чтобы это произошло до выполнения родительского кода. Наличие двух дочерних элементов и использование waitpid () x2 в родительском разделе приводит к зависанию. Мое намерение состоит в том, чтобы использовать первый аргумент waitpid (), чтобы указать каждого из двух потомков, которых нужно ждать. Насколько я понимаю, это допустимое использование waitpid ().
Я создал простой пример без трубы и только с одним дочерним элементом. Родитель использует waitpid () с дочерним pid в качестве первого аргумента. Это хорошо работает и подтверждает, что я правильно использую pid arg. Затем, вернувшись к исходному коду с двумя дочерними элементами (ниже), я попытался использовать -1 в качестве первого аргумента в каждом из waitpid (), так как я понимаю, что это более общий подход. Это все еще висит. Затем я подумал, что, возможно, поскольку дочерний процесс B ожидает выполнения дочернего процесса A, прежде чем он выполнит, к тому времени, когда родительский элемент дочернего процесса A его waitpid больше не будет изменять состояние, поэтому я попытался иметь только ожидание дочернего процесса B. Он все еще зависает. Я пытался добавить exit (0) в конец каждого блока кода каждого дочернего элемента, но я думаю, что это плохая идея, потому что тогда, когда достигается блок кода родительского элемента, дочерние элементы становятся зомби. Так что мой пробел в знаниях заключается в понимании того, когда именно дети меняют состояние и в какие моменты waitpid () может регистрировать эти изменения, а когда нет.
Система: Linux 5.1.15 и GCC 9.1.0 & bash 5.0.7 (1)
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
int main(){
pid_t child_a, child_b;
int fd_pipe[2];
if(pipe(fd_pipe) == -1){
fprintf(stderr, "pipe failed\n");
perror(NULL);
}
child_a = fork();
if(child_a < 0){
fprintf(stderr, "child_a fork failed\n");
perror(NULL);
}
else if(child_a == 0){
//child_a
printf("child_a pid: %d\n", getpid());
close(STDOUT_FILENO);
dup(fd_pipe[1]);
close(fd_pipe[0]);
close(fd_pipe[1]);
printf("test");
}
else{
child_b = fork();
if(child_b < 0){
fprintf(stderr, "child_b fork failed\n");
perror(NULL);
}
else if(child_b == 0){
//child_b
pid_t wait_ret = waitpid(child_a, NULL, 0);
printf("child_b pid: %d\n", getpid());
close(STDIN_FILENO);
dup(fd_pipe[0]);
close(fd_pipe[1]);
close(fd_pipe[0]);
char str[5];
scanf("%s",str);
printf("%d %s %d\n",getpid(), str, getpid());
}
else {
//parent
pid_t wait_ret = waitpid(child_a, NULL, 0);
wait_ret = waitpid(child_b, NULL, 0);
printf("parent pid: %d\n", getpid());
}
}
}
Я ожидаю, что ребенок A объявит о себе с помощью PID, а затем ребенок B объявит о себе с помощью PID вместе с выданным по трубопроводу печатным «тестом». И тогда я ожидаю, что родитель объявит о себе. Вместо этого я получаю начальные отпечатки детей A и B, а затем зависаю.