Está en la página 1de 35

Ejercicio 1 Realice un programa en C que en ejecucin resulten dos procesos, uno padre y otro hijo.

Dicho programa tomar un nico argumento del intrprete de rdenes, que se trata de un entero. El proceso padre incrementar dicho valor en 2 y lo mostrar por pantalla. El hijo lo decrementar en 4 y lo mostrar tambin por pantalla. Solucin: --Jatenor 10:38 24 nov 2010 (UTC) #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> int main(int argc, char *argv[]) { if(argc != 2) { printf("Numero de parametros incorrectos. Uso: %s [entero]\n",argv[0]); exit(EXIT_FAILURE); } int var=atoi(argv[1]); printf("Entrada: %d\n",var); int ret; ret=fork(); if(ret>0) { var+=2; printf(" %d\n",var); wait(NULL); } else if(ret == 0) { var-=4; printf("%d\n",var); exit(EXIT_SUCCESS); } else if(ret == -1) { perror("Fallo en fork()\n"); exit(EXIT_FAILURE); } } Solucin para comprobar que lo que le pasamos como argumento es un nmero --Raumatbel 14:22 24 nov 2010 (UTC) #include <stdlib.h>

#include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <string.h> // para calcular el tamao del argumento strlen(const char *s)

#include <ctype.h> // para comprobar si el argumento que le pasamos es un numero isdigit(char c)

int main(int argc, char *argv[]){

if(argc!=2){ printf("Numero de parametros incorrectos. Uso: %s [entero]\n",argv[0]); exit(EXIT_FAILURE); }

int ret;

// int atoi(char* cadena)

pasa de ASCII a INTEGER

int valor=atoi(argv[1]); char c; int i;

/*Mostrar el tamao del argumento*/

printf("el tamao de %s es: %d\n",argv[1],strlen(argv[1]));

/*Comprobar que lo que le pasamos como argumento (argv[1]) es un numero*/ for(i=0; i<strlen(argv[1]); i++){ c=argv[1][i]; if(isdigit(c)==0){ /* is digit(char c) comprueba si el caracter es un digito (de 0 a 9). ** Los valores devueltos son no-cero si el caracter c est dentro del rango (0-9), ** */ perror("fallo al insertar el argumento, debe de ser un numero"); exit(EXIT_FAILURE); } } y cero si no.

ret=fork();

if(ret==-1){ perror("fallo en el fork"); exit(EXIT_FAILURE); }

else if(ret>0){ valor+=2;

printf("El valor del padre es %d\n",valor); wait(NULL); } else if(ret==0){ valor-=4; printf("El valor del hijo es %d\n",valor); exit(EXIT_SUCCESS);

Ejercicio 2
Realice un programa en C que genere la siguiente configuracin de procesos: padre / | \ / | \ / | \ / | \ / | \ hijo1 hijo2 hijo3 Adems, cada hijo deber mostrar el mensaje "Yo soy el hijo 1, mi padre es PID=1450, yo soy PID=1453". Solucin:

--Markest 11:32 1 dic 2010 (UTC) #include #include #include #include #include <unistd.h> <stdlib.h> <stdio.h> <sys/types.h> <sys/wait.h>

#include <errno.h> #define NUM_HIJOS 3 /* nmero de hijos a crear. */ int main(void) { int ret, i; for (i=0; i<NUM_HIJOS; i++) { ret = fork(); if (ret == 0) { /* estamos en alguno de los hijos. */ printf("Yo soy el hijo %d, mi padre es PID= %d, yo soy PID= %d\n", i,getppid(), getpid()); exit(EXIT_SUCCESS); } else if (ret == -1) { perror("fallo en fork"); exit(EXIT_FAILURE); } } ret = wait(NULL); while (ret > 0) { ret = wait(NULL); } /* si hay error, ignoramos si no hay ms hijos a esperar. */ if (ret == -1 && errno != ECHILD) { perror("fallo en wait"); exit(EXIT_FAILURE); } }

Ejercicio 3
Realice un programa en C que genere la siguiente configuracin de procesos: padre | | | hijo1 | | | hijo2 | ... |

hijoN Adems, cada hijo deber mostrar el mensaje "Yo soy el hijo 1, mi padre es PID=1450, yo soy PID=1453". Use para este ejemplo N=3 Solucin: --Pedleogom 11:35 1 dic 2010 (UTC) #include #include #include #include #include #include <unistd.h> <stdlib.h> <stdio.h> <sys/types.h> <sys/wait.h> <errno.h>

#define NUM_HIJOS 3 /* nmero de hijos a crear. */ int main(void) { int ret, i; for (i=0; i<NUM_HIJOS; i++) { ret = fork(); if (ret == 0) { /* estamos en alguno de los hijos. */ printf("Yo soy el hijo %d, mi padre es PID= %d, yo soy PID= %d\n",i,getppid(),getpid()); //notese que NO usamos el exit(EXIT_SUCCESS) //a diferencia del ejercicio con hijos en paralelo //para que el hijo "i" se convierta en el padre del hijo "i+1" } else if (ret > 0) { /* tratamiento del padre */ ret = wait(NULL); while (ret > 0) { ret = wait(NULL); } if (ret == -1 && errno != ECHILD) { perror("fallo en wait"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } else if (ret == -1) {

perror("fallo en fork"); exit(EXIT_FAILURE); } } }

Ejercicio 4
Realice un programa en C que genere la siguiente configuracin de procesos: padre / \ / / / / hijo1 \ \ \ \ hijo2 | | | hijo3

Adems, cada hijo deber mostrar el mensaje "Yo soy el hijo 1, mi padre es PID=1450, yo soy PID=1453". Solucin: --J.J. Alczar 11:36 1 dic 2010 (UTC) #include #include #include #include #include #include <unistd.h> <stdlib.h> <stdio.h> <sys/types.h> <sys/wait.h> <errno.h>

#define NUM_HIJOS 2 /* nmero de hijos a crear. */ void lanzahijo3(int i) { int ret; ret = fork(); if (ret > 0) { wait(NULL); } else if (ret == 0) { printf("Yo soy el hijo %d, mi padre es PID=%d, yo soy PID=%d\n", i, getppid(), getpid());

} else if (ret == -1) { perror("fallo en fork"); exit(EXIT_FAILURE); } } int main(void) { int ret, i; for (i=0; i<NUM_HIJOS; i++) { ret = fork(); if (ret == 0) { /* estamos en alguno de los hijos. */ switch(i) { case 0: printf("Yo soy el hijo %d, mi padre es PID=%d, yo soy PID=%d\n", i, getppid(), getpid()); exit(EXIT_SUCCESS); case 1: printf("Yo soy el hijo %d, mi padre es PID=%d, yo soy PID=%d\n", i, getppid(), getpid()); lanzahijo3(i); exit(EXIT_SUCCESS); } } else if (ret == -1) { perror("fallo en fork"); exit(EXIT_FAILURE); } } ret = wait(NULL); while (ret > 0) { ret = wait(NULL); } /* si hay error, ignoramos si no hay ms hijos a esperar. */ if (ret == -1 && errno != ECHILD) { perror("fallo en wait"); exit(EXIT_FAILURE); } }

Ejercicios sobre la llamada exec


Ejercicio 1
Realice un programa en C que ejecute la orden ls -la. Nota: Realice la ejecucin en un proceso hijo.

Solucin: --Fmlopjur 09:33 1 dic 2010 (UTC) #include #include #include #include #include <unistd.h> <sys/types.h> <sys/wait.h> <stdio.h> <stdlib.h>

int main(void) { int ret; ret = fork(); if (ret > 0) { /* tratamiento del padre. */ wait(NULL); } else if (ret == 0) { /* tratamiento del hijo. */ execlp ("ls", "ls", "-la", NULL); perror("fallo en execlp"); exit(EXIT_FAILURE); } else if (ret == -1) { perror("fallo en fork"); exit(EXIT_FAILURE); } }

Ejercicio 2
Realice un programa en C que resulte en la siguiente configuracin de procesos: padre / \ / / / / hijo1 \ \ \ \ hijo2

El proceso hijo1 deber ejecutar la orden ls -la cuya salida, en lugar de mostrar el resultado por pantalla, se almacenar en el fichero hijo1.txt. El proceso hijo2 deber ejecutar la orden ps -ef, de igual manera se almacenar su salida en el fichero hijo2.txt. Solucin: --Jatenor 11:05 2 dic 2010 (UTC) #include <unistd.h> #include <stdlib.h>

#include #include #include #include #include #include

<stdio.h> <sys/wait.h> <errno.h> <sys/types.h> <sys/stat.h> <fcntl.h>

#define NUM_HIJOS 2 /* nmero de hijos a crear. */ void hijo1(); void hijo2(); int main(void) { int ret, i; for (i=0; i<NUM_HIJOS; i++) { ret = fork(); if (ret == 0) { /* estamos en alguno de los hijos. */ switch(i) { case 0: /* tratamiento hijo 1. */ hijo1(); exit(EXIT_SUCCESS); case 1: /* tratamiento hijo 2. */ hijo2(); exit(EXIT_SUCCESS); } } else if (ret > 0) { /* tratamiento del padre */ } else if (ret == -1) { perror("fallo en fork"); exit(EXIT_FAILURE); } } ret = wait(NULL); while (ret > 0) { ret = wait(NULL); } /* si hay error, ignoramos si no hay ms hijos a esperar. */ if (ret == -1 && errno != ECHILD) { perror("fallo en wait"); exit(EXIT_FAILURE);

} } void hijo1() { int fd; fd = open("hijo1.txt", O_WRONLY | O_CREAT |O_TRUNC, 0660); if(fd == -1){ perror("Fallo al abrir fichero hijo1.txt"); exit(EXIT_FAILURE); } dup2(fd, STDOUT_FILENO); /* La salida estandar ahora apunta a hijo1.txt y no a la pantalla*/ if(close(fd)==-1){ perror("fallo en close hijo1.txt"); exit(EXIT_FAILURE); } execlp("ls","ls","-la",NULL); perror("fallo en execlp"); } void hijo2() { int fd; fd = open("hijo2.txt", O_WRONLY | O_CREAT | O_TRUNC, 0660); if(fd == -1){ perror("Fallo al abrir fichero hijo2.txt"); exit(EXIT_FAILURE); } dup2(fd, STDOUT_FILENO); /* La salida estandar ahora apunta a hijo2.txt y no a la pantalla*/ if(close(fd)==-1){ perror("fallo en close hijo2.txt"); exit(EXIT_FAILURE); }

execlp("ps","ps","-ef",NULL); perror("fallo en execlp"); exit(EXIT_FAILURE); }

Ejercicio 3

Ejercicio sobre tuberas


Ejercicio 1
Realice un programa en C que resulte en la siguiente configuracin de procesos: padre / \ / / \ \

/ \ / \ hijo1 ------> hijo2 tubera

El proceso hijo1 tomar datos del teclado que enviar al proceso hijo2 a travs de una tubera, este ltimo mostrar el mensaje recibido por pantalla. La ejecucin de los procesos concluir cuando el proceso hijo1 reciba la cadena "fin". Solucin: #include #include #include #include #include #include #include <unistd.h> <stdlib.h> <stdio.h> <sys/types.h> <sys/wait.h> <errno.h> <string.h>

#define NUM_HIJOS 2 /* nmero de hijos a crear. */ void hijo1(int fds[2]) { int numbytes; char buf[4096]; close(fds[0]);

numbytes = read(STDIN_FILENO, buf, sizeof(buf)); while (numbytes > 0) { if (write(fds[1], buf, strlen(buf)) == -1) { perror("fallo en write"); exit(EXIT_FAILURE); } if (strncmp("fin\n", buf, strlen("fin\n")) == 0) break; numbytes = read(STDIN_FILENO, buf, sizeof(buf)); } if (numbytes == -1) { perror("fallo en read"); exit(EXIT_FAILURE); } close(fds[1]); } void hijo2(int fds[2]) { int numbytes; char buf[4096]; close(fds[1]); numbytes = read(fds[0], buf, sizeof(buf)); while (numbytes > 0) { if (strncmp("fin\n", buf, strlen("fin\n")) == 0) break; if (write(STDOUT_FILENO, buf, strlen(buf)) == -1) { perror("fallo en write"); exit(EXIT_FAILURE); } numbytes = read(fds[0], buf, sizeof(buf)); } if (numbytes == -1) { perror("fallo en read"); exit(EXIT_FAILURE); } close(fds[0]); } int main(void) { int ret, i, fds[2];

if (pipe(fds) == -1) { perror("fallo en pipe"); exit(EXIT_FAILURE); } for (i=0; i<NUM_HIJOS; i++) { ret = fork(); if (ret == 0) { /* estamos en alguno de los hijos. */ switch(i) { case 0: /* tratamiento hijo 1. */ hijo1(fds); exit(EXIT_SUCCESS); case 1: /* tratamiento hijo 2. */ hijo2(fds); exit(EXIT_SUCCESS); } } else if (ret > 0) { /* tratamiento del padre */ } else if (ret == -1) { perror("fallo en fork"); exit(EXIT_FAILURE); } } // El padre cierra la tubera antes de esperar y salir close(fds[0]); close(fds[1]); ret = wait(NULL); while (ret > 0) { ret = wait(NULL); } /* si hay error, ignoramos si no hay ms hijos a esperar. */ if (ret == -1 && errno != ECHILD) { perror("fallo en wait"); exit(EXIT_FAILURE); } } Solucin --Lus Mira Caballos 17:08 18 dic 2011 (UTC) Solucionado si la primera palabra es "fin" => se termina. Solucion limpieza del buffer antes de una lectura/escritura de palabras.

#include #include #include #include #include #include #include

<unistd.h> <stdlib.h> <stdio.h> <sys/types.h> <sys/wait.h> <errno.h> <string.h>

#define NUM_HIJOS 2 /* nmero de hijos a crear. */ #define LECTURA 0 #define ESCRITURA 1 void hijo1(int fd[2]); void hijo2(int fd[2]); void main (void){ int ret,i,fd[2]; if(pipe(fd)==-1){ perror("Error en la creacin de tubera.\n"); exit("EXIT_FAILURE"); } for(i=0;i<NUM_HIJOS;i++){ ret=fork(); if(ret==0){ switch (i){ case 0: hijo1(fd); exit(EXIT_SUCCESS); break; case 1: hijo2(fd); exit(EXIT_SUCCESS); break; default: perror("Error en el SWITCH.Se ha entrado en DEFAULT.\n"); exit(EXIT_FAILURE); break; } } if(ret>0){ /*ejecucin del padre*/ }

if(ret==-1){ fprintf(stderr,"Error en el FORK.%s\n",strerror(errno)); exit(EXIT_FAILURE); } } /*cierre de la tubera en el padre*/ close(fd[LECTURA]); close(fd[ESCRITURA]); ret=wait(NULL); /*el padre espera a la finalizacin de todos los hijos*/ while (ret>0){ ret=wait(NULL); } /* si hay error, ignoramos si no hay ms hijos a esperar. */ if(ret==-1 && errno!=ECHILD){ perror("Error en el WAIT.\n"); exit(EXIT_FAILURE); } } void hijo1(int fd[2]){ int fr; char bf[4096]={}; if(close(fd[LECTURA])==-1){ perror("Error en el cierre de LECTURA del hijo1.\n"); exit(EXIT_FAILURE); } fr=read(STDIN_FILENO,bf,sizeof(bf)); while(fr>0){ if (strncmp(bf,"fin",3)==0){ break; } if(write(fd[ESCRITURA],bf,strlen(bf))==-1){ perror("Error en la escritura de tubera en hijo1.\n"); exit(EXIT_FAILURE); } memset(bf,0,sizeof(bf));//coloca a 0 todos los elementos del array "bf".0=vacio fr=read(STDIN_FILENO,bf,sizeof(bf)); }

if (fr==-1){ perror("Error en la lectura en hijo1"); exit(EXIT_FAILURE); } if(close(fd[ESCRITURA])==-1){ perror("Error en el cierre de ESCRITURA del hijo1.\n"); exit(EXIT_FAILURE); } } void hijo2(int fd[2]){ int fr; char bf[4096]={}; if(close(fd[ESCRITURA])==-1){ perror("Error en el cierre de lectura del hijo2.\n"); exit (EXIT_FAILURE); } fr=read(fd[LECTURA],bf,sizeof(bf)); while(fr>0){ if (strncmp(bf,"fin",3)==0){ break; } if(write(STDOUT_FILENO,bf,strlen(bf))==-1){ perror("Error en la escritura del hijo2.\n"); exit(EXIT_FAILURE); } memset(bf,0,sizeof(bf));//coloca a 0 todos los elementos del array "bf".0=vacio fr=read(fd[LECTURA],bf,sizeof(bf)); } if(fr==-1){ perror("Error en la lectura de hijo2.\n"); exit(EXIT_FAILURE); } if(close(fd[LECTURA])==-1){ perror("Error en el cierre de lectura del hijo2.\n"); exit(EXIT_FAILURE); } }

Ejercicio 2
Realice un programa en C que resulte en la ejecucin de la siguiente orden: ls -la | grep ^d @Blindust: si subes una solucin, los ejercicios tienen que compilar y enlazar por lo menos, de ah que haya borrado tu solucin. --Pneira 12:39 14 dic 2010 (UTC) #include #include #include #include #include #include #include <unistd.h> <stdlib.h> <stdio.h> <sys/types.h> <sys/wait.h> <errno.h> <string.h>

#define NUM_HIJOS 2 /* nmero de hijos a crear. */ void hijo1(int fds[2]) { close(fds[0]); dup2(fds[1], STDOUT_FILENO); close(fds[1]); execlp("ls", "ls", "-la", NULL); perror("fallo en execlp"); exit(EXIT_FAILURE); } void hijo2(int fds[2]) { close(fds[1]); dup2(fds[0], STDIN_FILENO); close(fds[0]); execlp("grep", "grep", "^d", NULL); perror("fallo en execlp"); exit(EXIT_FAILURE); } int main(void) { int ret, i, fds[2]; if (pipe(fds) == -1) { perror("fallo en pipe"); exit(EXIT_FAILURE);

} for (i=0; i<NUM_HIJOS; i++) { ret = fork(); if (ret == 0) { /* estamos en alguno de los hijos. */ switch(i) { case 0: /* tratamiento hijo 1. */ hijo1(fds); exit(EXIT_SUCCESS); case 1: /* tratamiento hijo 2. */ hijo2(fds); exit(EXIT_SUCCESS); } } else if (ret > 0) { /* tratamiento del padre */ } else if (ret == -1) { perror("fallo en fork"); exit(EXIT_FAILURE); } } /* tratamiento del padre una vez lanzados ambos hijos. */ close(fds[0]); close(fds[1]); ret = wait(NULL); while (ret > 0) { ret = wait(NULL); } /* si hay error, ignoramos si no hay ms hijos a esperar. */ if (ret == -1 && errno != ECHILD) { perror("fallo en wait"); exit(EXIT_FAILURE); } }

Ejercicio 3
Realice un programa en C que resulte en la siguiente configuracin de procesos: padre / \ / / / \ \ \

/ \ hijo1 ------> hijo2 tubera

El proceso hijo1 ejecutar la orden ls -la. El resultado de dicha ejecucin, en lugar de ser mostrado por pantalla, se comunicar al proceso hijo2 que lo almacenar en el fichero salida_ls_la.txt. @Blindust: si subes una solucin, los ejercicios tienen que compilar y enlazar por lo menos, de ah que haya borrado tu solucin. --Pneira 12:40 14 dic 2010 (UTC) Solucin: --Fpalomares 16:55 14 dic 2010 (UTC) #include #include #include #include #include #include #include #include <unistd.h> <stdlib.h> <stdio.h> <sys/types.h> <sys/wait.h> <errno.h> <string.h> <fcntl.h>

#define NUM_HIJOS 2 /* nmero de hijos a crear. */ void hijo1(int fds[2]) { close(fds[0]); dup2(fds[1], STDOUT_FILENO); close(fds[1]); execlp("ls", "ls", "-la", NULL); perror("fallo en execlp"); exit(EXIT_FAILURE); } void hijo2(int fds[2]) { int fd, numbytes; char buf[4096]; close(fds[1]); fd = open("./salida_ls_la.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666); if(fd==-1){ perror("Error en open"); exit(EXIT_FAILURE); }

numbytes = read(fds[0],buf,sizeof(buf)); while (numbytes > 0) { if (write(fd, buf, strlen(buf)) == -1) { perror("fallo en write"); exit(EXIT_FAILURE); } numbytes = read(fds[0], buf, sizeof(buf)); } if (numbytes == -1) { perror("fallo en read"); exit(EXIT_FAILURE); } close(fds[0]); if(close(fd)){ perror("Error en close"); exit(EXIT_FAILURE); } } int main(void) { int ret, i, fds[2]; if (pipe(fds) == -1) { perror("fallo en pipe"); exit(EXIT_FAILURE); } for (i=0; i<NUM_HIJOS; i++) { ret = fork(); if (ret == 0) { /* estamos en alguno de los hijos. */ switch(i) { case 0: /* tratamiento hijo 1. */ hijo1(fds); exit(EXIT_SUCCESS); case 1: /* tratamiento hijo 2. */ hijo2(fds); exit(EXIT_SUCCESS); } } else if (ret > 0) { /* tratamiento del padre */ } else if (ret == -1) { perror("fallo en fork");

exit(EXIT_FAILURE); } } /* tratamiento del padre una vez lanzados ambos hijos. */ close(fds[0]); close(fds[1]); ret = wait(NULL); while (ret > 0) { ret = wait(NULL); } /* si hay error, ignoramos si no hay ms hijos a esperar. */ if (ret == -1 && errno != ECHILD) { perror("fallo en wait"); exit(EXIT_FAILURE); } }

Ejercicio 4
Realice un programa en C denominado ping-pong. Dicho programa consistir en dos procesos hijos. El proceso hijo1 enviar la cadena "ping" a lo que el proceso hijo2 responder con la cadena "pong". La ejecucin se limitar a diez iteraciones, tras lo cual ambos procesos terminarn su ejecucin. Solucin: --marjimlao 00:18 16 dic 2010 (UTC) #include #include #include #include #include #include #include <unistd.h> <stdlib.h> <stdio.h> <sys/types.h> <sys/wait.h> <errno.h> <string.h>

#define NUM_HIJOS 2 /* nmero de hijos a crear. */ char *ping = "PING"; char *pong = "PONG"; int hijo1(int fds[2], int fds2[2]) { char buf[4096]; int count = 0; if(close(fds[0])==-1){ perror("fallo al cerrar el primer pipe");

exit(EXIT_FAILURE); } if(close(fds2[1])==-1){ perror("fallo al cerrar el primer pipe"); exit(EXIT_FAILURE); } write(fds[1], ping,strlen(ping)); printf("%s\n", ping); count++; while(count < 10){ read(fds2[0], buf, sizeof(buf)); if((strcmp(buf, pong))==0){ printf("%s\n", ping); write(fds[1], ping,strlen(ping)); count++; } } if(close(fds2[0])==-1){ perror("fallo al cerrar el primer pipe"); exit(EXIT_FAILURE); } if(close(fds[1])==-1){ perror("fallo al cerrar el primer pipe"); exit(EXIT_FAILURE); } }

int hijo2(int fds[2], int fds2[2]) { char buf[4096]; int count = 0; if(close(fds2[0])==-1){ perror("fallo al cerrar el primer pipe"); exit(EXIT_FAILURE); } if(close(fds[1])==-1){ perror("fallo al cerrar el primer pipe"); exit(EXIT_FAILURE); } while(count < 10){ read(fds[0], buf, sizeof(buf)); if((strcmp(buf, ping))==0){ printf("%s\n", pong);

write(fds2[1], pong,strlen(pong)); count++; } } if(close(fds[0])==-1){ perror("fallo al cerrar el primer pipe"); exit(EXIT_FAILURE); } if(close(fds2[1])==-1){ perror("fallo al cerrar el primer pipe"); exit(EXIT_FAILURE); } } int main(void) { int ret, i, fds[2], fds2[2]; if (pipe(fds) == -1) { perror("fallo en pipe"); exit(EXIT_FAILURE); } if(pipe(fds2)==-1){ perror("fallo en pipe 2"); exit(EXIT_FAILURE); } for (i=0; i<NUM_HIJOS; i++) { ret = fork(); if (ret == 0) { /* estamos en alguno de los hijos. */ switch(i) { case 0: /* tratamiento hijo 1. */ hijo1(fds, fds2); exit(EXIT_SUCCESS); case 1: /* tratamiento hijo 2. */ hijo2(fds, fds2); exit(EXIT_SUCCESS); } } else if (ret > 0) { /* tratamiento del padre */ } else if (ret == -1) { perror("fallo en fork"); exit(EXIT_FAILURE);

} } ret = wait(NULL); while (ret > 0) { ret = wait(NULL); } /* si hay error, ignoramos si no hay ms hijos a esperar. */ if (ret == -1 && errno != ECHILD) { perror("fallo en wait"); exit(EXIT_FAILURE); } }

Ejercicio 5
Realice un programa en C que resulte en la ejecucin de la siguiente orden: ls -la | grep ^d | tail -1

--Fmlopjur 08:29 15 dic 2010 (UTC) Solucin: #include #include #include #include #include #include #include <unistd.h> <stdlib.h> <stdio.h> <sys/types.h> <sys/wait.h> <errno.h> <string.h>

#define NUM_HIJOS 2 /* nmero de hijos a crear. */ void hijo1(int fds[2], int fds2[2]) { close(fds2[0]); close(fds2[1]); close(fds[0]); dup2(fds[1], STDOUT_FILENO); close(fds[1]); execlp("ls", "ls", "-la", NULL); perror("fallo en execlp"); exit(EXIT_FAILURE); }

void hijo2(int fds[2], int fds2[2]) {

close(fds2[0]); dup2(fds2[1], STDOUT_FILENO); close(fds2[1]); close(fds[1]); dup2(fds[0], STDIN_FILENO); close(fds[0]); execlp("grep", "grep", "^d", NULL); perror("fallo en execlp"); exit(EXIT_FAILURE); } void hijo3(int fds[2], int fds2[2]) { close(fds[0]); close(fds[1]); close(fds2[1]); dup2(fds2[0], STDIN_FILENO); close(fds2[0]); execlp("tail", "tail", "-1", NULL); perror("fallo en execlp"); exit(EXIT_FAILURE); } int main(void) { int ret, i, fds[2], fds2[2]; if (pipe(fds) == -1) { perror("fallo en pipe"); exit(EXIT_FAILURE); } if (pipe(fds2) == -1) { perror("fallo en pipe"); exit(EXIT_FAILURE); } /*CREAR 3 HIJOS EN PARALELO*/ for (i=0; i<=NUM_HIJOS; i++) { ret = fork(); if (ret == 0) { /* estamos en alguno de los hijos. */

switch(i) { case 0: /* tratamiento hijo 1. */ hijo1(fds, fds2); exit(EXIT_SUCCESS); case 1: /* tratamiento hijo 2. */ hijo2(fds, fds2); exit(EXIT_SUCCESS); case 2: /* tratamiento hijo 3. */ hijo3(fds, fds2); exit(EXIT_SUCCESS); } } else if (ret > 0) { /* tratamiento del padre */ } else if (ret == -1) { perror("fallo en fork"); exit(EXIT_FAILURE); } } /* tratamiento del padre una vez lanzados ambos hijos. */ close(fds[0]); close(fds[1]); close(fds2[0]); close(fds2[1]); ret = wait(NULL); while (ret > 0) { ret = wait(NULL); } /* si hay error, ignoramos si no hay ms hijos a esperar. */ if (ret == -1 && errno != ECHILD) { perror("fallo en wait"); exit(EXIT_FAILURE); } }

Ejercicio 6
Realice un programa en C que resulte en la siguiente configuracin de procesos: padre | | hijo1

| | hijo2

Los procesos hijo1 e hijo2 generarn un nmero aleatorio cada uno de ellos que comunicarn el uno al otro. Ambos mostrarn el siguiente mensaje por pantalla: Soy hijo1 con PID=1567, mi nmero aleatorio es 10 y el del otro proceso es 32 Soy hijo2 con PID=1568, mi nmero aleatorio es 32 y el del otro proceso es 10

Para la generacin de nmeros aleatorios use la siguiente implementacin: #include <stdlib.h> #include <time.h> int aleatorio(void) { int semilla = (int)time(NULL); srand(semilla); } que genera un nmero aleatorio. Solucin El mtodo de generar nmeros aleatorios no funciona. He puesto nmeros manualmente para probar que el cdigo funciona correctamente. --AlvaroSG 12:15 22 dic 2010 (UTC) #include #include #include #include #include #include #include #include #include #include #include #include <stdlib.h> <time.h> <unistd.h> <stdlib.h> <stdio.h> <sys/types.h> <sys/wait.h> <errno.h> <string.h> <sys/types.h> <sys/stat.h> <fcntl.h>

#define lectura 0 #define escritura 1

int aleatorio(void) { int semilla = (int)time(NULL); srand(semilla); } int hijo(int tube1[2], int tube2[2]){ int ret; int minumero; int numbytes; char buf[256]={}; ret = fork(); if (ret == 0){ /*Tratamiento del nieto*/ //minumero = aleatorio(); minumero= 6; printf("%d\n",minumero); sprintf(buf,"%d",minumero); if( write (tube1[escritura],buf, sizeof(buf)) == 1){ perror("Fallo write nieto"); exit(EXIT_FAILURE); } numbytes = read(tube2[lectura],buf,sizeof(buf)); if (numbytes == -1){ perror("Fallo read nieto"); exit(EXIT_FAILURE); }

close(tube1[escritura]); close(tube2[lectura]);

printf("Soy hijo2 con PID=%d, mi nmero aleatorio es %d y el del otro proceso es %s\n",getpid(),minumero,buf);

} else if (ret > 0){ /*Tratamiento del padre*/ //minumero = aleatorio(); minumero=5; printf("%d\n",minumero); sprintf(buf,"%d",minumero); if( write (tube2[escritura],buf, sizeof(buf)) == 1){ perror("Fallo write padre"); exit(EXIT_FAILURE); } numbytes = read(tube1[lectura],buf,sizeof(buf)); if (numbytes == -1){ perror("Fallo read padre"); exit(EXIT_FAILURE); }

close(tube1[lectura]); close(tube2[escritura]); printf("Soy hijo2 con PID=%d, mi nmero aleatorio es %d y el del otro proceso es %s\n",getpid(),minumero,buf); } else if (ret == -1){ /*Error*/ perror("Fallo en el segundo fork"); exit(EXIT_FAILURE); } }

int main (void){ int ret; int ret2; int tube1[2]; int tube2[2]; int temp; int e; char buf[256]={}; if (pipe(tube1) == -1){ perror("Fallo pipe1"); exit(EXIT_FAILURE); } if (pipe(tube2) == -1){ perror("Fallo pipe2"); exit(EXIT_FAILURE); } ret = fork(); if (ret == 0){ /*tratamiento del hijo*/ hijo(tube1,tube2); } else if( ret > 0){ /*tratamiento del abuelo*/

} else if (ret == -1){ /*error*/ perror("Fallo en fork"); exit(EXIT_FAILURE); } ret = wait (NULL); while (ret > 0){ ret = wait(NULL); }

if (ret == -1 && errno != ECHILD){ perror("Fallo en wait"); exit (EXIT_FAILURE); } }

Ejercicio 5 (Complemento)
Realice un programa en C que resulte en la ejecucin de la siguiente orden: ls -la | grep ^d | tail -1 > salida.txt

--Fmlopjur 17:15 15 dic 2010 (UTC) Solucin: #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/wait.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define NUM_HIJOS 3 /* nmero de hijos a crear. */ void hijo1(int fds[2], int fds2[2]) { close(fds2[0]); close(fds2[1]); close(fds[0]); dup2(fds[1], STDOUT_FILENO); close(fds[1]); execlp("ls", "ls", "-la", NULL); perror("fallo en execlp"); exit(EXIT_FAILURE); } void hijo2(int fds[2], int fds2[2]) {

close(fds2[0]);

dup2(fds2[1], STDOUT_FILENO); close(fds2[1]); close(fds[1]); dup2(fds[0], STDIN_FILENO); close(fds[0]); execlp("grep", "grep", "^d", NULL); perror("fallo en execlp"); exit(EXIT_FAILURE); } void hijo3(int fds[2], int fds2[2]) { int fd; fd = open("salida.txt", O_WRONLY | O_CREAT | O_TRUNC, 0600); if(fd == -1){ perror("fallo en open\n"); exit(EXIT_FAILURE); } dup2(fd, STDOUT_FILENO); if(close(fd)){ perror("fallo en close\n"); exit(EXIT_FAILURE); } close(fds[0]); close(fds[1]); close(fds2[1]); dup2(fds2[0], STDIN_FILENO); close(fds2[0]); execlp("tail", "tail", "-1", NULL); perror("fallo en execlp"); exit(EXIT_FAILURE); } int main(void) { int ret, i, fds[2], fds2[2]; if (pipe(fds) == -1) { perror("fallo en pipe"); exit(EXIT_FAILURE); } if (pipe(fds2) == -1) { perror("fallo en pipe"); exit(EXIT_FAILURE); }

/*CREAR 3 HIJOS EN PARALELO*/ for (i=0; i<=NUM_HIJOS; i++) { ret = fork(); if (ret == 0) { /* estamos en alguno de los hijos. */ switch(i) { case 0: /* tratamiento hijo 1. */ hijo1(fds, fds2); exit(EXIT_SUCCESS); case 1: /* tratamiento hijo 2. */ hijo2(fds, fds2); exit(EXIT_SUCCESS); case 2: /* tratamiento hijo 3. */ hijo3(fds, fds2); exit(EXIT_SUCCESS); } } else if (ret > 0) { /* tratamiento del padre */ } else if (ret == -1) { perror("fallo en fork"); exit(EXIT_FAILURE); } } /* tratamiento del padre una vez lanzados ambos hijos. */ close(fds[0]); close(fds[1]); close(fds2[0]); close(fds2[1]); ret = wait(NULL); while (ret > 0) { ret = wait(NULL); } /* si hay error, ignoramos si no hay ms hijos a esperar. */ if (ret == -1 && errno != ECHILD) { perror("fallo en wait"); exit
navegacin

Pgina Principal

Portal de la comunidad Actualidad Cambios recientes Pgina aleatoria Ayuda


Ir Buscar

buscar

herramientas

Lo que enlaza aqu Cambios relacionados Pginas especiales Versin para imprimir Enlace permanente

Esta pgina fue modificada por ltima vez

También podría gustarte