Ejercicio Fork
-
Upload
rdelgado28 -
Category
Documents
-
view
159 -
download
21
Transcript of Ejercicio Fork
Ejercicio 1
Realice un programa en C que en ejecución resulten dos procesos, uno padre y otro hijo. Dicho programa tomará un único argumento del intérprete 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á también por pantalla.
Solución: --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);
}}
Solución para comprobar que lo que le pasamos como argumento es un número
--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 tamaño 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 tamaño del argumento*/
printf("el tamaño 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),
** y cero si no.
*/
perror("fallo al insertar el argumento, debe de ser un numero");
exit(EXIT_FAILURE);
}
}
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 configuración de procesos:
padre / | \ / | \ / | \ / | \ / | \ hijo1 hijo2 hijo3
Además, cada hijo deberá mostrar el mensaje "Yo soy el hijo 1, mi padre es PID=1450, yo soy
PID=1453".
Solución:
--Markest 11:32 1 dic 2010 (UTC)
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#define NUM_HIJOS 3 /* número 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 más 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 configuración de procesos:
padre | | | hijo1 | | | hijo2 | ...
| hijoN
Además, 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
Solución:
--Pedleogom 11:35 1 dic 2010 (UTC)
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#define NUM_HIJOS 3 /* número 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 configuración de procesos:
padre / \ / \ / \ / \ / \ hijo1 hijo2 | | | hijo3
Además, cada hijo deberá mostrar el mensaje "Yo soy el hijo 1, mi padre es PID=1450, yo soy
PID=1453".
Solución:
--J.J. Alcázar 11:36 1 dic 2010 (UTC)
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#define NUM_HIJOS 2 /* número 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 más hijos a esperar. */
if (ret == -1 && errno != ECHILD) {
perror("fallo en wait");
exit(EXIT_FAILURE);
}
}
Ejercicios sobre la llamada execEjercicio 1
Realice un programa en C que ejecute la orden ls -la. Nota: Realice la ejecución en un proceso
hijo.
Solución: --Fmlopjur 09:33 1 dic 2010 (UTC)
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <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 configuración 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.
Solución: --Jatenor 11:05 2 dic 2010 (UTC)
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define NUM_HIJOS 2 /* número 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 más 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 tuberías
Ejercicio 1
Realice un programa en C que resulte en la siguiente configuración de procesos:
padre / \ / \ / \ / \ / \ hijo1 ------> hijo2 tubería
El proceso hijo1 tomará datos del teclado que enviará al proceso hijo2 a través de una tubería, este
último mostrará el mensaje recibido por pantalla. La ejecución de los procesos concluirá cuando el
proceso hijo1 reciba la cadena "fin".
Solución:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
#define NUM_HIJOS 2 /* número 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 tubería 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 más hijos a esperar. */
if (ret == -1 && errno != ECHILD) {
perror("fallo en wait");
exit(EXIT_FAILURE);
}
}
Solución --Luís 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 <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
#define NUM_HIJOS 2 /* número 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 creación de tubería.\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){
/*ejecución del padre*/
}
if(ret==-1){
fprintf(stderr,"Error en el FORK.%s\
n",strerror(errno));
exit(EXIT_FAILURE);
}
}
/*cierre de la tubería en el padre*/
close(fd[LECTURA]);
close(fd[ESCRITURA]);
ret=wait(NULL);
/*el padre espera a la finalización de todos los hijos*/
while (ret>0){
ret=wait(NULL);
}
/* si hay error, ignoramos si no hay más 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 tubería 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 ejecución de la siguiente orden:
ls -la | grep ^d
@Blindust: si subes una solución, los ejercicios tienen que compilar y enlazar por lo menos, de ahí
que haya borrado tu solución. --Pneira 12:39 14 dic 2010 (UTC)
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
#define NUM_HIJOS 2 /* número 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 más 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 configuración de procesos:
padre / \ / \ / \
/ \ / \ hijo1 ------> hijo2 tubería
El proceso hijo1 ejecutará la orden ls -la. El resultado de dicha ejecución, 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 solución, los ejercicios tienen que compilar y enlazar por lo menos, de ahí
que haya borrado tu solución. --Pneira 12:40 14 dic 2010 (UTC)
Solución: --Fpalomares 16:55 14 dic 2010 (UTC)
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#define NUM_HIJOS 2 /* número 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 más 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 ejecución se limitará a diez iteraciones, tras lo cual ambos procesos terminarán su
ejecución.
Solución: --marjimlao 00:18 16 dic 2010 (UTC)
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
#define NUM_HIJOS 2 /* número 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 más 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 ejecución de la siguiente orden:
ls -la | grep ^d | tail -1
--Fmlopjur 08:29 15 dic 2010 (UTC)
Solución:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
#define NUM_HIJOS 2 /* número 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 más 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 configuración de procesos:
padre
| | hijo1 | | hijo2
Los procesos hijo1 e hijo2 generarán un número aleatorio cada uno de ellos que comunicarán el
uno al otro. Ambos mostrarán el siguiente mensaje por pantalla:
Soy hijo1 con PID=1567, mi número aleatorio es 10 y el del otro proceso es 32Soy hijo2 con PID=1568, mi número aleatorio es 32 y el del otro proceso es 10
Para la generación de números aleatorios use la siguiente implementación:
#include <stdlib.h>
#include <time.h>
int aleatorio(void)
{
int semilla = (int)time(NULL);
srand(semilla);
}
que genera un número aleatorio.
Solución
El método de generar números aleatorios no funciona. He puesto números manualmente para
probar que el código funciona correctamente.
--AlvaroSG 12:15 22 dic 2010 (UTC)
#include <stdlib.h>
#include <time.h>
#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 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 número 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 número 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 ejecución de la siguiente orden:
ls -la | grep ^d | tail -1 > salida.txt
--Fmlopjur 17:15 15 dic 2010 (UTC)
Solución:
#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 /* número 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 más hijos a esperar. */
if (ret == -1 && errno != ECHILD) {
perror("fallo en wait");
exit
navegación
Página Principal
Portal de la comunidad
Actualidad
Cambios recientes
Página aleatoria
Ayuda buscar
herramientas
Lo que enlaza aquí
Cambios relacionados
Páginas especiales
Versión para imprimir
Enlace permanente
Esta página fue modificada por última vez
Ir Buscar