Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: PeKiN en 28 Marzo 2011, 22:39 pm



Título: Comunicacion entre procesos hijo en C
Publicado por: PeKiN en 28 Marzo 2011, 22:39 pm
Hola! queria saber si existe alguna forma para comunicar dos procesos hijo en C, intercambiando informacion entre ellos una vez ejecutados.

Gracias de ante mano


Título: Re: Comunicacion entre procesos hijo en C
Publicado por: Akai en 28 Marzo 2011, 23:23 pm
Si estás en un sistema tipo Unix, utilizar tuberías puede ser una opción.

El procedimiento sería crear las tuberías desde el padre, crear los hijos, cerrar las tuberías en el padre y como los hijos heredan los descriptores de ficheros del padre, que estos  utilicen como entrada y/o salida las tuberías. que el padre tenía abiertas en el momento de crear los hijos.

dup2 y pipe son las funciones usadas para ello.

En un sistema Windows no sabría decirte.


Título: Re: Comunicacion entre procesos hijo en C
Publicado por: PeKiN en 28 Marzo 2011, 23:29 pm
Primeramente gracias por la respeusta Akai. Efectivamente, estoy en un sistema Unix, me había planteado utilizar sockets porque nunca antes usé tuberias, pero quizá sea una opción mas eficiente la de las tuberías. ¿podrias ponerme un ejemplo a nivel de código donde se utilicen estas ideas que me pones?

Gracias de ante mano!


Título: Re: Comunicacion entre procesos hijo en C
Publicado por: Akai en 29 Marzo 2011, 00:16 am
Si, esto sería un pequeño shell de una práctica de la facultad donde se utiliza esto:

Esto crea tantos hijos como ordenes hay, y luego cada hijo hace hace un exec para cambiarse por el programa que realmente nos interesa poner en su lugar.

Esto se plantea como que el shell crea 2 hijos cuando tu le pides ejecutar "ls -la | grep root"

el primer hijo se hace un exec a "ls -la" y el segundo a "grep root"

Código
  1. for(i=0;i<nordenes;i++){
  2. forkpid=fork();
  3. if(forkpid==0){
  4. redirigir_entrada(i);
  5. redirigir_salida(i);
  6. cerrar_fd();
  7. if(-1==execvp(ordenes[i],args[i]))
  8. exit(-1);
  9. }
  10. else if(forkpid==-1){
  11. return ERROR;
  12. }
  13. else{
  14.  
  15. }
  16. }
  17. cerrar_fd();

Pero antes de ese código se preparan los canales de esta forma:
cmdfd es una estructura que contiene dos enteros, infd y outfd.
Código
  1. for(i=0;i<ncmd-1;i++){
  2.        pipe(fds);
  3.        cmdfd[i].outfd=fds[1];
  4.        cmdfd[i+1].infd=fds[0];
  5.    }
Para las órdenes que haya, se crean n-1 tuberias.

(revisa la referencia de pipe y dup2)

y redirigir la entrada o salida sería esto:

Código
  1. int redirigir_entrada(int i){
  2.    if(cmdfd[i].infd!=0){ //evitar redirigir la entrada estándar sobre si misma, perdida de tiempo.
  3.        if(-1!=dup2(cmdfd[i].infd,0))
  4.            return OK;
  5.        return ERROR;
  6.        }
  7.    return OK;
  8. }
  9.  
  10. int redirigir_salida(int i){
  11. if(cmdfd[i].outfd!=1){ //evitar redirigir la salida estándar sobre si misma, perdida de tiempo
  12. if(-1!=dup2(cmdfd[i].outfd,1))
  13. return OK;
  14. return ERROR;
  15. }
  16.    return OK;
  17. }
  18. int cerrar_fd(){
  19.    int i;
  20.    for(i=3;i<=nds+2;i++){ //nds +2 es el numero del último descriptor de fichero activo.
  21.        close(i);
  22.        }
  23.    return OK;
  24. }
  25.  


Posiblemente encuentres por ahí un código más claro, pero lo básico es:

Preparar canales
Crear hijos
Cerrar canales del padre si no se tiene que comunicar con los hijos
Que los hijos se redirijan las entradas / salidas y cerrar los descriptores sobrantes
A correr.

EDIT: editados los comentarios del código.