¿Es posible tener un conducto entre dos procesos secundarios creados por el mismo elemento primario (LINUX, POSIX)?

Tengo varios hijos “bifurcados” por el mismo padre e bash construir una conexión de conexión entre todos estos procesos secundarios, como una estructura de lista vinculada. El niño 1 envía datos a child2, child 2 a child 3 …. child N a child 1. ¿Hay alguna forma adecuada de hacerlo?

Además, si creo y me comunico entre procesos, waitpid() al padre a “esperar” todo el proceso para finalizar su trabajo, ya que wait() o waitpid() esperan el primer proceso finalizado, pero debo esperarlos todos. Es la otra pregunta que surge.

Gracias…

Esto es esencialmente lo que hace un shell si construye una cadena de redirección, es decir, algo así como

 ls | grep foo | sort | uniq 

Hay algunos textos introductorios excelentes sobre la progtwigción de Unix, en los que se implementa un simple shell a través del libro. Y una de las tareas de un shell es la redirección. Uno de estos libros es “Progtwigción de aplicaciones Linux” por Michael K. Johnson y Erik W. Troan.

La página principal del libro: http://ladweb.net/

Para construir una cadena de redirecciones para N procesos, necesita tubos N-1. Para cada redirección, crea una tubería utilizando la llamada al sistema pipe(int fds[2]) . Después de fork() , pero antes de execv use dup2(int from, int to) para “conectar” el extremo de una tubería a la entrada estándar (0) o salida estándar de cada proceso. Aquí hay un código demasiado simplificado, sin verificación de errores:

 int pipe_A[2]; int pipe_B[2]; pipe(pipe_A); pipe(pipe_B); pid_t pid_A, pid_B, pid_C; if( !(pid_A = fork()) ) { dup2(pipe_A[1], 1); /* redirect standard output to pipe_A write end */ execv(...); } if( !(pid_B = fork()) ) { dup2(pipe_A[0], 0); /* redirect standard input to pipe_A read end */ dup2(pipe_B[1], 1); /* redirect standard output to pipe_B write end */ execv(...); } if( !(pid_C = fork()) ) { dup2(pipe_B[0], 0); /* redirect standard input to pipe_B read end */ execv(...); } 

Tenga en cuenta que los índices de matriz de la tubería se han elegido de forma que reflejen los descriptores de archivos de entrada / salida estándar si se usan para la redirección de stdio. Esta elección no fue arbitraria.

Por supuesto, puede conectar tuberías a cualquier descriptor de archivo (por ejemplo, hay algunas aplicaciones que esperan que sus padres se abran, digamos fd 3 y 4, conectadas a las tuberías) y la mayoría de las shells también admiten esto (por ejemplo, 1> & 3 redireccionará stdout en fd 3). Sin embargo, los índices de matriz para pipe(int fds[2]) son 0 y 1, por supuesto. Solo digo esto, porque tenía algunos estudiantes de progtwigción de culto de carga, que sin pensar tomaron los fds de destino también para el arreglo de syscall de tubería.

Para esperar a que todos los hijos terminen el uso waitpid(-1, NULL, 0) – Creo que ese es el -1 que mi pre-answerer quiso decir, lo que significa: Espere a que todos los procesos secundarios finalicen. La otra opción era llamar a wait() en un bucle que devolverá el pid del hijo recién terminado. Si se llama nuevamente y aún hay un hijo en ejecución, se bloqueará nuevamente. Si no queda ningún niño, devolverá -1; Yo prefiero la solución de waitpid .

Sí, esto es bastante fácil, solo necesita crear todos los tubos en el elemento primario, y recuerde cerrar los tubos / extremos de los tubos en los elementos secundarios en los que no los necesita.

Dejar FDs de las tuberías abiertas en niños que no los están utilizando es FALLO, ya que puede hacer que otros esperen por siempre para el final de la tubería. Todos los escritores deben cerrar antes de que el lector obtenga un EOF.

Primero crea todas las tuberías y luego engendra a todos los niños con los extremos apropiados en los FDs 0 y 1.

En cuanto a esperar, solo sigue esperando hasta que devuelva -1.