-1- Arquitectura de Computadores Práctica 3: Mecanismos de comunicación entre procesos Miguel Martínez de Falcón Pérez Mikel Anthony Rodríguez Manderson -2- 1) TUBERÍAS SIN NOMBRE a) Para comprobar su funcionamiento, ejecutamos el programa y observamos como introduciendo la cadena por teclado, el padre la pasaba al pipe. Tras esto el hijo la cogía del pipe y mostraba la cadena de caracteres por pantalla. Es importante observar como el pipe, al ser común para ambos procesos (padre e hijo) se crea antes de crear el proceso hijo, de forma que sea una variable común a ambos. b) #define #define #define #define #define MAXLINE 4096 MSG0 "PADRE: Introduzca una cadena de MSG1 "PADRE: Enviada cadena\n" MSG2 "\tHIJO: Informacion recibida\n" MSG3 "PADRE: Terminado...\n" caracteres\n" int main() { int tubo[2],n; pid_t mipid; char cadena[MAXLINE]; char line[MAXLINE]; // Creamos el pipe tubo para comunicar el padre y el hijo if(pipe(tubo)<0) { perror("pipe()"); exit(-1); } // Creamos el proceso HIJO mipid=fork(); if(mipid<0) { perror("fork()"); exit(-2); } // Proceso PADRE else if(mipid) { printf("%s",MSG0); // Lee la cadena de caracteres introducida por teclado y la almacena en cadena n=read(STDIN_FILENO,cadena,MAXLINE); // Cierra el descriptor para la lectura de datos del pipe close(tubo[0]); // Escribe la cadena de caracteres en el pipe write(tubo[1],cadena,n); printf("%s",MSG1); // Cierra el descriptor para la escritura de datos en el pipe close(tubo[1]); wait(NULL); printf("%s",MSG3); exit(0); } // Proceso HIJO else -3- { // Cierra el descriptor para la escritura de datos en el pipe close(tubo[1]); // Lee la cadena de caracteres del pipe y la almacena en line read(tubo[0],line,MAXLINE); printf("%s",MSG2); sleep(1); // Muestra la cadena de caracteres por pantalla printf("%s",line); // Cierra el descriptor para la lectura de datos del pipe close(tubo[0]); exit(0); } } -4- c) #define #define #define #define #define MAXLINE 4096 MSG0 "PADRE: Introduzca una cadena de MSG1 "PADRE: Enviada cadena\n" MSG2 "\tHIJO: Informacion recibida\n" MSG3 "PADRE: Terminado...\n" caracteres\n" int main() { // Definimos las variables de nuestro programa int tubo1[2],tubo2[2],n; pid_t mipid; char cadena[MAXLINE]; char line[MAXLINE]; // Creamos los pipes tubo1 y tubo2 para comunicar el padre y el hijo if(pipe(tubo1)<0) { perror("pipe()"); exit(-1); } if(pipe(tubo2)<0) { perror("pipe()"); exit(-1); } // Creamos el proceso hijo mipid=fork(); if(mipid<0) { perror("fork()"); exit(-2); } else if(mipid) { // Proceso padre printf("%s",MSG0); // Lee la cadena de caracteres introducida por teclado y la almacena en cadena n=read(STDIN_FILENO,cadena,MAXLINE); // Cierra el descriptor para la lectura de datos del pipe tubo1 close(tubo1[0]); // Cierra el descriptor para la escritura de datos del pipe tubo2 close(tubo2[1]); // Escribe la cadena de caracteres en el pipe tubo1 write(tubo1[1],cadena,n); printf("%s",MSG1); wait(NULL); // Lee la cadena de caracteres que le envia el hijo por tubo2 y la muestra por pantalla n=read(tubo2[0],cadena,(strlen(MSG2)-1)*sizeof(char)); printf("%s\n",cadena); // Cierra el descriptor para la escritura de datos del pipe tubo1 -5- close(tubo1[1]); // Cierra el descriptor para la lectura de datos del pipe tubo2 close(tubo2[0]); printf("%s",MSG3); exit(0); } else { // Proceso hijo // Cierra el descriptor para la escritura de datos del pipe tubo1 close(tubo1[1]); // Cierra el descriptor para la lectura de datos del pipe tubo2 close(tubo2[0]); // Lee la cadena de caracteres del pipe tubo1 y la almacena en line read(tubo1[0],line,MAXLINE); // Escribe la cadena MSG2 en el pipe tubo2 write(tubo2[1],MSG2,strlen(MSG2)*sizeof(char)); sleep(1); // Muestra la cadena de caracteres por pantalla printf("%s",line); // Cierra el descriptor para la lectura de datos del pipe tubo1 close(tubo1[0]); // Cierra el descriptor para la escritura de datos del pipe tubo2 close(tubo2[1]); exit(0); } } -6- 2) TUBERÍAS CON NOMBRE a) int main(int argc,char *argv[]) { int p; // Comprobamos que la sintaxis sea correcta if(argc!=2) { printf("Modo de empleo: fifos <nombre_tuberia>\n"); exit(-1); } // Creamos la tubería con los permisos adecuados if((p=mkfifo(argv[1],0644))==-1) { perror("mkfifo()"); exit; } } El programa genera un pipe cuyo nombre será el parámetro pasado al programa. Se puede ver como los permisos son de lectura y escritura para el creador mientras que el resto de usuarios solo tienen permisos de lectura. Ejecutando el programa, podemos ver el pipe generado con un ls –l viendo como los permisos son los adecuados. b) Hemos comprobado que la tubería tiene los permisos adecuados, al volver a crear una tubería con el mismo nombre nos sale un error que dice: mkfifo(): File Exists