Descarga la aplicación para disfrutar aún más
Esta es una vista previa del archivo. Inicie sesión para ver el archivo original
SO2/Atexit.pdf Área de Arquitectura y Tecnología de Computadores EUPT: Sistemas Operativos II 1 Finalización de Procesos 1- Formas normales a) Retorno desde la función main b) Llamando a la función exit c) Llamando a la función _exit 2- Formas anormales d) Llamando a la función abort e) Terminación a causa de una señal (signal) Nota: Si la llamada a la función exit( ) estuviese escrita en C, la llamada a la función main( ) podría realizarse de la forma : exit(main(argc, argv)); Funciones para la finalización normal de un proceso: _exit: retorna inmediatamente del kernel _exit - terminate the current process #include <unistd.h> void _exit(int status); exit: realiza algunas labores de limpieza y retorna del kernel exit - cause normal program termination #include <stdlib.h> void exit(int status); exit realiza un “clean shutdown” de la “standard I/O library”:se llama a la función fclose para todos los “open streams” (todos los datos de salida “buffered” son escritos en los ficheros, “flushed”) Nota: Las diferentes cabeceras se deben a que exit está especificada por ANSI C, mientras que _exit está especificada por POSIX.1 exit() y _exit() tienen un único argumento entero que se denomina “exit status”. El “exit status” de un proceso está indefinido en los siguientes casos: a) main realiza un return sin un valor de return b) Si _exit o exit son llamadas sin un “exit status” c) Si main realiza un return implícito Nota: Casi todos los shells Unix permiten recoger el “exit status” de un proceso. Área de Arquitectura y Tecnología de Computadores EUPT: Sistemas Operativos II 2 Función atexit() Con ANSI C un proceso puede registrar hasta 32 funciones que pueden ser llamadas automáticamente por exit. Estas funciones se denominan “exit handlers” y se registran llamando a la función atexit( ) atexit - register a function to be called at normal program termination. #include <stdlib.h> int atexit(void (*function)(void)); Devuelve: 0 si OK, no cero si error. La función exit( ) llama a estas funciones en orden inverso a su registro. Los “exit handlers” aparecen con ANSI C y se suministran para SVR4 y 4.3+BSD Con ANSI C y POSIX.1, exit( ) primero llama a los “exit handlers” y luego “fcloses” los “open streams”. Ejemplo: // Finalizanción de procesos: atexit( ) #include "error.h" static void exit1(); static void exit2(); int main( ) { if (atexit(exit2) != 0) error("No se registro exit2"); if (atexit(exit1) != 0) error("No se registro exit1"); printf("\n main se acabo \n"); exit(0); } static void exit1() { printf("\n exit handler 1 \n"); } static void exit2() { printf("\n exit handler 2 \n"); } SO2/Practicas_SOII/Ejercicios Operativos I/anillo.c /* *** anillo.c *** Área de Arquitectura y Tecnología de Computadores EUPT: Sistemas Operativos II */ #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <signal.h> #include <stdlib.h> int Realiza_Operacion(int num_1, int num_2); void handler(); int hijo1, hijo2, hijo3; int main(int argc, char *argv[]){ int pid_t, pidaux, pidwait; int numero, alarma, nuevo_numero, nbytes; int buf = 0, status = 0, cont_hijos_fin = 0; int fpipe[3][2]; pipe(fpipe[0]); pipe(fpipe[1]); pipe(fpipe[2]); numero = atoi(argv[1]); alarma = atoi(argv[2]); printf("\n Paso 1 del testigo: %d", numero); printf("\n Tiempo máximo permitido para la ejecución %d seg.\n", alarma); alarm(alarma); fflush(stdout); sleep(1); if ((hijo1 = fork()) == 0) { close(fpipe[0][1]); close(fpipe[1][0]); close(fpipe[2][0]); close(fpipe[2][1]); read(fpipe[0][0], &buf, 4); nuevo_numero = Realiza_Operacion(numero, buf); printf("\n Paso 2 del testigo: %d", nuevo_numero); fflush(stdout); write(fpipe[1][1], &nuevo_numero, 4); exit(1); } if ((hijo2 = fork()) == 0) { close(fpipe[0][0]); close(fpipe[0][1]); close(fpipe[1][1]); close(fpipe[2][0]); read(fpipe[1][0], &buf, 4); nuevo_numero = Realiza_Operacion(numero, buf); printf("\n Paso 3 del testigo: %d", nuevo_numero); fflush(stdout); write(fpipe[2][1], &nuevo_numero, 4); exit(2); } if ((hijo3 = fork()) == 0) { close(fpipe[0][0]); close(fpipe[1][0]); close(fpipe[1][1]); close(fpipe[2][1]); read(fpipe[2][0], &buf, 4); nuevo_numero = Realiza_Operacion(numero, buf); printf("\n Paso 4 del testigo: %d", nuevo_numero); fflush(stdout); write(fpipe[0][1], &nuevo_numero, 4); exit(3); } signal(SIGALRM, handler); sleep(10); //Todos los procesos hijos deben de estar en ejecucion write(fpipe[0][1], &numero, 4); close(fpipe[0][1]); nbytes = read(fpipe[0][0], &buf, 4); waitpid(hijo1, &status, 0); printf("\n Proceso %d ha finalizado y su estado es %d", hijo1, status); waitpid(hijo2, &status, 0); printf("\n Proceso %d ha finalizado y su estado es %d", hijo2, status); waitpid(hijo3, &status, 0); printf("\n Proceso %d ha finalizado y su estado es %d", hijo3, status); if (nbytes == 4) printf("\n El resultado de la ejecución del anillo es: %d \n", buf); else printf("\n La ejecución del anillo ha sido INCORRECTA. \n"); exit(0); } int Realiza_Operacion(int num_1, int num_2) { int num_opera; /* */ // Nuevo código de la función; /* */ num_opera = num_1 * num_2; return(num_opera); } void handler() { kill(hijo1, SIGKILL); kill(hijo2, SIGKILL); kill(hijo3, SIGKILL); printf("La ejecucion ha sido abortada por incumpliento del tiempo"); exit(-1); } SO2/Practicas_SOII/Ejercicios Operativos I/dimepar.c // // DIMEPAR.C // #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> int main(int argc, char * argv[]) { int numero, result=1; int status=1; numero = atoi(argv[1]); if (fork()==0) execl("./par", "par", argv[1], NULL); else { wait(&status); result=(status); if (result == 1) printf("\n El numero %d: es PAR \n", numero); else if (result == 0) printf("\n El numero %d: es IMPAR \n", numero); } return(0); } SO2/Practicas_SOII/Ejercicios Operativos I/impar.c #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> #include "itoa.c" int main(int argc, char * argv[]) { int numimpar; int presult; int status; char buf[10]; numimpar=atoi(argv[1]); if(numimpar == 0) exit(0); else { numimpar = numimpar - 1; itoa(numimpar, buf); if (fork()==0) execl("./par", "par", buf, NULL); else { wait(&status); presult=status/256; //printf("hola"); exit(presult); } } } SO2/Practicas_SOII/Ejercicios Operativos I/itoa.c #include <string.h> /* reverse: reverse string s in place */ void reverse(char s[]) { int i, j; char c; for (i = 0, j = strlen(s)-1; i<j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } } /* itoa: convert n to characters in s */ void itoa(int n, char s[]) { int i, sign; if ((sign = n) < 0) /* record sign */ n = -n; /* make n positive */ i = 0; do { /* generate digits in reverse order */ s[i++] = n % 10 + '0'; /* get next digit */ } while ((n /= 10) > 0); /* delete it */ if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s); } SO2/Practicas_SOII/Ejercicios Operativos I/listaP.c # include <stdio.h> int pid_padre, pid_hijo, i=1; int repeticiones=3; int main () { pid_padre=getpid(); printf("Soy el proceso creador %d; \n", pid_padre); while (i<=repeticiones) { if (fork()!=0) { sleep(1); exit(0); } else{ pid_padre=getppid(); pid_hijo=getpid(); printf("Soy el nuevo proceso %d; mi padre es %d; \n", pid_hijo, pid_padre); printf("Mi numero de orden es %d; \n", i); while (getppid()!=1) { wait(); } printf("Mi padre ha finalizado, ahora soy el proceso maestro \n"); i++; } } exit(0); } SO2/Practicas_SOII/Ejercicios Operativos I/par.c #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> #include "itoa.c" int main(int argc, char * argv[]) { int presult; int numpar; int status; char buf[10]; numpar=atoi(argv[1]); if(numpar == 0) exit(1); else { numpar = numpar - 1; itoa(numpar, buf); //printf(buf); if (fork()==0) execl("./impar", "impar", buf, NULL); else { //printf("hola"); wait(&status); presult=(status/256); exit(presult); } } } // /* itoa: convert n to characters in s */ // void itoa(int n, char s[]) // { // int i, sign; // // if ((sign = n) < 0) /* record sign */ // n = -n; /* make n positive */ // i = 0; // do { /* generate digits in reverse order */ // s[i++] = n % 10 + '0'; /* get next digit */ // } while ((n /= 10) > 0); /* delete it */ // if (sign < 0) // s[i++] = '-'; // s[i] = '\0'; // reverse(s); // } // // // // // /* reverse: reverse string s in place */ // void reverse(char s[]) // { // int i, j; // char c; // // for (i = 0, j = strlen(s)-1; i<j; i++, j--) { // c = s[i]; // s[i] = s[j]; // s[j] = c; // } SO2/Practicas_SOII/Ejercicios Operativos I/Problema_1/listaP.c # include <stdio.h> int pid_padre, pid_hijo, i=1; int repeticiones=3; int main () { pid_padre=getpid(); printf("Soy el proceso creador %d; \n", pid_padre); while (i<=repeticiones) { if (fork()!=0) { sleep(1); exit(0); } else{ pid_padre=getppid(); pid_hijo=getpid(); printf("Soy el nuevo proceso %d; mi padre es %d; \n", pid_hijo, pid_padre); printf("Mi numero de orden es %d; \n", i); while (getppid()!=1) { wait(); } printf("Mi padre ha finalizado, ahora soy el proceso maestro \n"); i++; } } exit(0); } SO2/Practicas_SOII/Ejercicios Operativos I/Problema_2/anillo.c /* *** anillo.c *** Área de Arquitectura y Tecnología de Computadores EUPT: Sistemas Operativos II */ #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <signal.h> #include <stdlib.h> int Realiza_Operacion(int num_1, int num_2); void handler(); int hijo1, hijo2, hijo3; int main(int argc, char *argv[]){ int pid_t, pidaux, pidwait; int numero, alarma, nuevo_numero, nbytes; int buf = 0, status = 0, cont_hijos_fin = 0; int fpipe[3][2]; pipe(fpipe[0]); pipe(fpipe[1]); pipe(fpipe[2]); numero = atoi(argv[1]); alarma = atoi(argv[2]); printf("\n Paso 1 del testigo: %d", numero); printf("\n Tiempo máximo permitido para la ejecución %d seg.\n", alarma); alarm(alarma); fflush(stdout); sleep(1); if ((hijo1 = fork()) == 0) { close(fpipe[0][1]); close(fpipe[1][0]); close(fpipe[2][0]); close(fpipe[2][1]); read(fpipe[0][0], &buf, 4); nuevo_numero = Realiza_Operacion(numero, buf); printf("\n Paso 2 del testigo: %d", nuevo_numero); fflush(stdout); write(fpipe[1][1], &nuevo_numero, 4); exit(1); } if ((hijo2 = fork()) == 0) { close(fpipe[0][0]); close(fpipe[0][1]); close(fpipe[1][1]); close(fpipe[2][0]); read(fpipe[1][0], &buf, 4); nuevo_numero = Realiza_Operacion(numero, buf); printf("\n Paso 3 del testigo: %d", nuevo_numero); fflush(stdout); write(fpipe[2][1], &nuevo_numero, 4); exit(2); } if ((hijo3 = fork()) == 0) { close(fpipe[0][0]); close(fpipe[1][0]); close(fpipe[1][1]); close(fpipe[2][1]); read(fpipe[2][0], &buf, 4); nuevo_numero = Realiza_Operacion(numero, buf); printf("\n Paso 4 del testigo: %d", nuevo_numero); fflush(stdout); write(fpipe[0][1], &nuevo_numero, 4); exit(3); } signal(SIGALRM, handler); sleep(10); //Todos los procesos hijos deben de estar en ejecucion write(fpipe[0][1], &numero, 4); close(fpipe[0][1]); nbytes = read(fpipe[0][0], &buf, 4); waitpid(hijo1, &status, 0); printf("\n Proceso %d ha finalizado y su estado es %d", hijo1, status); waitpid(hijo2, &status, 0); printf("\n Proceso %d ha finalizado y su estado es %d", hijo2, status); waitpid(hijo3, &status, 0); printf("\n Proceso %d ha finalizado y su estado es %d", hijo3, status); if (nbytes == 4) printf("\n El resultado de la ejecución del anillo es: %d \n", buf); else printf("\n La ejecución del anillo ha sido INCORRECTA. \n"); exit(0); } int Realiza_Operacion(int num_1, int num_2) { int num_opera; /* */ // Nuevo código de la función; /* */ num_opera = num_1 * num_2; return(num_opera); } void handler() { kill(hijo1, SIGKILL); kill(hijo2, SIGKILL); kill(hijo3, SIGKILL); printf("La ejecucion ha sido abortada por incumpliento del tiempo"); exit(-1); } SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/dimepar SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/dimepar.c // // DIMEPAR.C // #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> int main(int argc, char * argv[]) { int numero, result=1; int status=1; numero = atoi(argv[1]); if (fork()==0) execl("./par", "par", argv[1], NULL); else { wait(&status); result=(status/256); if (result == 1) printf("\n El numero %d: es PAR \n", numero); else if (result == 0) printf("\n El numero %d: es IMPAR \n", numero); } return(0); } SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/dimepar.c~ // // DIMEPAR.C // #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> int main(int argc, char * argv[]) { int numero, result=1; int status=1; numero = atoi(argv[1]); if (fork()==0) execl("./par", "par", argv[1], NULL); else { wait(&status); result=(status); if (result == 1) printf("\n El numero %d: es PAR \n", numero); else if (result == 0) printf("\n El numero %d: es IMPAR \n", numero); } return(0); } SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/impar SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/impar.c #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> #include "itoa.c" int main(int argc, char * argv[]) { int numimpar; int presult; int status; char buf[10]; numimpar=atoi(argv[1]); if(numimpar == 0) exit(0); else { numimpar = numimpar - 1; itoa(numimpar, buf); if (fork()==0) execl("./par", "par", buf, NULL); else { wait(&status); presult=status/256; //printf("hola"); exit(presult); } } } SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/itoa.c #include <string.h> /* reverse: reverse string s in place */ void reverse(char s[]) { int i, j; char c; for (i = 0, j = strlen(s)-1; i<j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } } /* itoa: convert n to characters in s */ void itoa(int n, char s[]) { int i, sign; if ((sign = n) < 0) /* record sign */ n = -n; /* make n positive */ i = 0; do { /* generate digits in reverse order */ s[i++] = n % 10 + '0'; /* get next digit */ } while ((n /= 10) > 0); /* delete it */ if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s); } SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/par SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/par.c #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> #include "itoa.c" int main(int argc, char * argv[]) { int presult; int numpar; int status; char buf[10]; numpar=atoi(argv[1]); if(numpar == 0) exit(1); else { numpar = numpar - 1; itoa(numpar, buf); //printf(buf); if (fork()==0) execl("./impar", "impar", buf, NULL); else { //printf("hola"); wait(&status); presult=(status/256); exit(presult); } } } SO2/Practicas_SOII/Ejercicios Operativos I/Problema_3/par.c~ #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> #include "itoa.c" int main(int argc, char * argv[]) { int presult; int numpar; int status; char buf[10]; numpar=atoi(argv[1]); if(numpar == 0) exit(1); else { numpar = numpar - 1; itoa(numpar, buf); //printf(buf); if (fork()==0) execl("./impar", "impar", buf, NULL); else { //printf("hola"); wait(&status); presult=(status/256); exit(presult); } } } // /* itoa: convert n to characters in s */ // void itoa(int n, char s[]) // { // int i, sign; // // if ((sign = n) < 0) /* record sign */ // n = -n; /* make n positive */ // i = 0; // do { /* generate digits in reverse order */ // s[i++] = n % 10 + '0'; /* get next digit */ // } while ((n /= 10) > 0); /* delete it */ // if (sign < 0) // s[i++] = '-'; // s[i] = '\0'; // reverse(s); // } // // // // // /* reverse: reverse string s in place */ // void reverse(char s[]) // { // int i, j; // char c; // // for (i = 0, j = strlen(s)-1; i<j; i++, j--) { // c = s[i]; // s[i] = s[j]; // s[j] = c; // } SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/char SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/char.c #include <sys/types.h> #include <stdio.h> void charatatime(char *str); int main() { pid_t pid; if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) charatatime("salida del hijo \n"); else { charatatime("salida del padre \n"); } exit(0); } void charatatime(char *str) { char *ptr; int c; setbuf(stdout, NULL); ptr = str; do { c = *ptr; putc(c, stdout); } while (*ptr++ != '\0'); } SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/char.c~ #include <sys/types.h> #include <stdio.h> void charatatime(char *str); int main() { pid_t pid; if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) charatatime("salida del hijo \n"); else { wait(); charatatime("salida del padre \n"); } exit(0); } void charatatime(char *str) { char *ptr; int c; setbuf(stdout, NULL); ptr = str; do { c = *ptr; putc(c, stdout); } while (*ptr++ != '\0'); } SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/charv2 SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/charv2.c #include <sys/types.h> #include <stdio.h> void charatatime(char *str); int main() { pid_t pid; if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) charatatime("salida del hijo \n"); else { wait(); charatatime("salida del padre \n"); } exit(0); } void charatatime(char *str) { char *ptr; int c; setbuf(stdout, NULL); ptr = str; do { c = *ptr; putc(c, stdout); } while (*ptr++ != '\0'); } SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/charv2.c~ #include <sys/types.h> #include <stdio.h> void charatatime(char *str); int main() { pid_t pid; if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) charatatime("salida del hijo \n"); else { charatatime("salida del padre \n"); } exit(0); } void charatatime(char *str) { char *ptr; int c; setbuf(stdout, NULL); ptr = str; do { c = *ptr; putc(c, stdout); } while (*ptr++ != '\0'); } SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/charv3 SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/charv3.c #include <sys/types.h> #include <stdio.h> void charatatime(char *str); int main() { pid_t pid; if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) { wait(); charatatime("salida del hijo \n"); } else { charatatime("salida del padre \n"); } exit(0); } void charatatime(char *str) { char *ptr; int c; setbuf(stdout, NULL); ptr = str; do { c = *ptr; putc(c, stdout); } while (*ptr++ != '\0'); } SO2/Practicas_SOII/Ejercicios Operativos I/Problema_4/charv3.c~ #include <sys/types.h> #include <stdio.h> void charatatime(char *str); int main() { pid_t pid; if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) { wait(); charatatime("salida del hijo \n"); exit(0); } else { charatatime("salida del padre \n"); } exit(0); } void charatatime(char *str) { char *ptr; int c; setbuf(stdout, NULL); ptr = str; do { c = *ptr; putc(c, stdout); } while (*ptr++ != '\0'); } SO2/Practicas_SOII/Ejercicios Operativos I/Problema_5/sigpipe SO2/Practicas_SOII/Ejercicios Operativos I/Problema_5/sigpipe.c #include <stdio.h> #include <signal.h> #include <unistd.h> void handler(); int main() { char* mensaje="hola"; int df[2]; pipe(df); signal(SIGPIPE, handler); if (fork()==0) { close(df[0]); } else { close(df[0]); write(df[1], mensaje, 5); } } void handler() { printf("Señal SIGPIPE controlada. \n"); } SO2/Practicas_SOII/Ejercicios Operativos I/Problema_5/sigpipe.c~ #include <stdio.h> #include <signal.h> #include <unistd.h> void handler(); int main() { char* mensaje="hola"; int df[2]; pipe(df); if (fork()==0) { close(df[0]); } else { close(df[0]); write(df[1], mensaje, 5); } } void handler() { printf("Señal SIGPIPE controlada. \n"); } SO2/Practicas_SOII/Ejercicios Operativos I/Problema_6/interprete.c SO2/Practicas_SOII/fuentes_luisapa/calcular.x /* Luis C. Aparicio Sistemas Operativos Área de Arquitectura y Tecnología de computadores Fichero de interfaz para la definición de las llamadas a procedimientos remotos (RPC). calcular.x */ program CALCULAR { version UNO { int sumar(int a, int b) = 1; int restar(int a, int b) = 2; } = 1; } = 497307; SO2/Practicas_SOII/fuentes_luisapa/clientRPC.c /* Luis C. Aparicio Sistemas Operativos Área de Arquitectura y Tecnología de computadores Programa cliente para la suma y resta de dos enteros utilizando RPC clientRPC.c */ #include "calcular.h" int main(int argc, char *argv[]) { int num1, num2; char *host; CLIENT *sv; int *ressum, *resres; host = argv[1]; num1 = atoi(argv[2]); num2 = atoi(argv[3]); sv = clnt_create(host, CALCULAR, UNO, "tcp"); if (sv == NULL) { clnt_pcreateerror(host); exit(0); } ressum = sumar_1(num1, num2, sv); if (ressum == NULL) { clnt_perror(sv, "error en suma RPC"); exit(0); } printf ("La suma %d + %d = %d \n", num1, num2, *ressum); resres = restar_1(num1, num2, sv); if (resres == NULL) { clnt_perror(sv, "error en resta RPC"); exit(0); } printf ("La resta %d - %d = %d \n", num1, num2, *resres); clnt_destroy(sv); exit(0); } SO2/Practicas_SOII/fuentes_luisapa/clieTCP.c /* Luis C. Aparicio Sistemas Operativos Área de Arquitectura y Tecnología de computadores Programa cliente para la suma utilizando sockets stream (TCP) clieTCP.c */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> int main(int argc, char *argv[]) { struct sockaddr_in server_addr; struct hostent *hp; char *namehost; int sd, puerto, res; int num[2]; /* Tratamiento de parámetros */ namehost = argv[1]; puerto = atoi(argv[2]); num[0] = atoi(argv[3]); num[1] = atoi(argv[4]); sd = socket(AF_INET, SOCK_STREAM, 0); /* Se obtine y se rellena la dirección del servidor */ bzero((char *)&server_addr, sizeof(server_addr)); /* hp = gethostbyname("esquinazo.unizar.es"); */ hp = gethostbyname(namehost); if (hp == NULL) { printf("\n Error en la llamada gethostbyname"); exit(0); } bcopy (hp->h_addr, (char *)&(server_addr.sin_addr), hp->h_length); server_addr.sin_family = AF_INET; /*server_addr.sin_port = htons(4200); */ server_addr.sin_port = htons(puerto); /* Se establece la conexión */ if (connect(sd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) { perror("\n Error en la llamada connect"); exit(0); } /* envía la petición */ //write(sd, (char *) num, 2 *sizeof(int)); write(sd, &num, 2 *sizeof(int)); /* recibe la respuesta */ //read(sd, (char *)&res, sizeof(int)); read(sd, &res, sizeof(int)); printf("\n El resultado es %d \n", res); close(sd); exit(0); } SO2/Practicas_SOII/fuentes_luisapa/clieUDP.c /* Luis C. Aparicio Sistemas Operativos EUPT: Área de Arquitectura y Tecnología de computadores Programa cliente para la suma utilizando sockets datagram (UDP) clieUDP.c */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> int main(int argc, char *argv[]) { struct sockaddr_in server_addr, client_addr; struct hostent *hp; char *namehost; int sd, puerto, res; int num[2]; /* Tratamiento de parámetros */ namehost = argv[1]; puerto = atoi(argv[2]); num[0] = atoi(argv[3]); num[1] = atoi(argv[4]); sd = socket(AF_INET, SOCK_DGRAM, 0); /* Se optine y se rellena la dirección del servidor */ bzero((char *)&server_addr, sizeof(server_addr)); /* hp = gethostbyname("esquinazo.unizar.es"); */ hp = gethostbyname(namehost); if (hp == NULL) { printf("\n Error en la llamada gethostbyname"); exit(0); } bcopy (hp->h_addr, (char *)&(server_addr.sin_addr), hp->h_length); server_addr.sin_family = AF_INET; /*server_addr.sin_port = htons(4400); */ server_addr.sin_port = htons(puerto); /* Se rellena la dirección del cliente, cuando se utiliza el número de puerto 0, el sistema se encarga de asignarle uno */ bzero((char *) &client_addr, sizeof(client_addr)); client_addr.sin_family = AF_INET; client_addr.sin_addr.s_addr = INADDR_ANY; client_addr.sin_port = htons(0); /* puerto asignado por el sistema */ bind(sd, (struct sockaddr *)&client_addr, sizeof(client_addr)); //sendto(sd, (char *)num, 2 * sizeof(int), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); sendto(sd, num, 2 * sizeof(int), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); //recvfrom(sd, (char *)&res, sizeof(int), 0, NULL, NULL); recvfrom(sd, &res, sizeof(int), 0, NULL, NULL); printf("\n El resultado es %d \n", res); close(sd); exit(0); } SO2/Practicas_SOII/fuentes_luisapa/echoall SO2/Practicas_SOII/fuentes_luisapa/error.h /*** *** *** *** *** ***/ /* // LUIS CARLOS APARICIO CARDIEL // Sistemas Operativos I // Ingenieria Tecnica en Informatica de Gestion // error.h // En este fichero se define la funcion syserr() // Incluir "error.h" detras de todos los demas includes */ #include<errno.h> #include<stdio.h> void syserr(char *men) { extern int errno, sys_nerr; extern char *sys_errlist[]; fprintf(stderr, "Error %s (%d", men, errno); if (errno > 0 && errno < sys_nerr) fprintf(stderr, "; %s)\n", sys_errlist[errno]); else fprintf(stderr, ")\n"); exit( 1 ); } void error(char *men) { extern int errno, sys_nerr; extern char *sys_errlist[]; fprintf(stderr, "Error %s (%d", men, errno); if (errno > 0 && errno < sys_nerr) fprintf(stderr, "; %s)\n", sys_errlist[errno]); else fprintf(stderr, ")\n"); exit( 2 ); } SO2/Practicas_SOII/fuentes_luisapa/funcpri.c #include "funcpri.h" long cuenta_primos(long min, long max) { long i, contador; contador = 0; for (i = min; i <= max; i++) if (esprimo(i)) contador = contador + 1; return (contador); } long encuentra_primos(long min, long max, long vector[]) { long i, contador; contador = 0; for (i = min; i <= max; i++) if (esprimo(i)) vector[contador++] = i; return (contador); } int esprimo(long n) { long i; for (i = 2; i*i <= n; i++) if ((n % i) == 0) return (0); return (1); } SO2/Practicas_SOII/fuentes_luisapa/funcpri.h #include <stdio.h> #define MINIMO 1L #define MAXIMO 1000000L /* Cuenta los primos entre min y max */ long cuenta_primos(long min, long max); /* Cuenta y encuentra los primos entre min y max y los devuelve en un vector */ long encuentra_primos(long min, long max, long vector[]); /* Devuelve TRUE si n es primo */ int esprimo(long n); SO2/Practicas_SOII/fuentes_luisapa/prac1.c /* Sistemas Operativos II */ /* prac1.c */ #include <sys/types.h> #include <unistd.h> int main() { int glob = 6; char buf[] = "Mensaje para la salida estándar \n"; int var = 88; pid_t pid; if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1) perror("write error"); printf("Mensaje antes de función fork \n"); if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) { glob++; var++; } else sleep(2); printf("pid = %d, glob = %d, var = %d \n", getpid(), glob, var); exit(0); } SO2/Practicas_SOII/fuentes_luisapa/prac10.c /* Sistemas Operativos II */ /* prac10.c */ #include <unistd.h> #include <sys/times.h> #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> void do_cmd(char *cmd); void pr_times(clock_t real, struct tms *tmsstar, struct tms *tmsend); void pr_exit(int estado); int main(int argc, char *argv[]) { int i; for (i = 1; i < argc; i++) do_cmd(argv[i]); exit(0); } void do_cmd(char *cmd) { struct tms tmsstart, tmsend; clock_t start, end; int status; fprintf(stderr, "\n command: %s \n", cmd); if ((start = times (&tmsstart)) == -1) perror("times error"); if ((status = system(cmd)) < 0) perror("system() error"); if ((end = times(&tmsend)) == -1) perror("times error"); pr_times(end - start, &tmsstart, &tmsend); pr_exit(status); } void pr_times(clock_t real, struct tms *tmsstart, struct tms *tmsend) { static long clktck = 0; if (clktck == 0) if ((clktck = sysconf(_SC_CLK_TCK)) < 0) perror("sysconf error"); fprintf(stderr, " real: %7.2f \n", real / (double) clktck); fprintf(stderr, " user: %7.2f \n", (tmsend->tms_utime - tmsstart->tms_utime) / (double) clktck); fprintf(stderr, " sys: %7.2f \n", (tmsend->tms_stime - tmsstart->tms_stime) / (double) clktck); fprintf(stderr, " child user: %7.2f \n", (tmsend->tms_cutime - tmsstart->tms_cutime) / (double) clktck); fprintf(stderr, " child sys: %7.2f \n", (tmsend->tms_cstime - tmsstart->tms_cstime) / (double) clktck); } void pr_exit(int estado) { if (WIFEXITED(estado)) printf("Terminacion normal, exit status = %d\n", WEXITSTATUS(estado)); else if (WIFSIGNALED(estado)) { printf("Terminacion anormal, numero de signal = %d ", WTERMSIG(estado)); if (WCOREDUMP(estado)) printf("(se genero fichero core)\n"); else printf(" \n"); } else if (WIFSTOPPED(estado)) printf("Hijo detenido, numero de signal = %d\n", WSTOPSIG(estado)); } SO2/Practicas_SOII/fuentes_luisapa/prac11.c /* Sistemas Operativos II */ /* prac11.c */ #include <stdio.h> #define READ 0 /* Indice de la terminacion de lectura del pipe */ #define WRITE 1 /* Indice de la terminacion de escritura del pipe */ char *frase = "Soy el proceso hijo y me encuentro bien"; int main() { int fd[2]; int bytesRead; char mensaje[100]; /* Buffer de mensajes del proceso padre */ pipe (fd); /* Creacion de un unnamed pipe */ if (fork() == 0) /* El hijo escritor */ { close(fd[READ]); /* Cierro terminacion del pipe no usada */ write(fd[WRITE], frase, strlen(frase)+1); /* Incluye NULL */ close(fd[WRITE]); } else /* El padre lector */ { close(fd[WRITE]); /* Cierre terminacion del pipe no usada */ bytesRead = read(fd[READ], mensaje, 100); printf("El padre ha leido %d bytes: %s \n", bytesRead, mensaje); close(fd[READ]); } exit(0); } SO2/Practicas_SOII/fuentes_luisapa/prac13.c /* Sistemas Operativos II */ /* prac13.c */ #include <sys/wait.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #define DEF_PAGER "/usr/bin/more" /* paginador por defecto */ #define MAXLINE 4096 int main(int argc, char *argv[]) { int n; int fd[2]; pid_t pid; char line[MAXLINE]; char *s; char *pager, *argv0; FILE *fp; if (argc != 2) { perror("usage: a.out <pathname>"); exit(1); } if ((fp = fopen (argv[1], "r")) == NULL) { perror(argv[1]); exit(1); } if (pipe(fd) < 0) perror("Error en pipe"); if ((pid = fork()) < 0) perror("Error en fork"); else if (pid > 0) { close(fd[0]); while (fgets(line, MAXLINE, fp) != NULL) { n = strlen(line); if (write(fd[1], line, n) != n) perror("Error de escritura en la pipe"); } if (ferror(fp)) perror("Error en fgets"); close(fd[1]); if (waitpid(pid, NULL, 0) < 0) perror ("Error en waitpid"); exit(0); } else { close(fd[1]); if (fd[0] != STDIN_FILENO) { if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) perror("dup2 error to stdin"); close(fd[0]); } if ((pager = getenv("PAGER")) == NULL) pager = DEF_PAGER; if ((argv0 = strrchr(pager, '/')) != NULL) argv0++; else argv0 = pager; if (execl(pager, argv0, 0) < 0) perror(pager); } } SO2/Practicas_SOII/fuentes_luisapa/prac16.c /* Sistemas Operativos II */ /* prac16.c */ #include <stdio.h> #define READ 0 #define WRITE 1 int main(int argc, char *argv[]) { int fd[2]; pipe(fd); /* Creación de unnamed pipe */ if (fork() != 0) /* Padre escritor */ { close(fd[READ]); /* Cierre terminal no usada de la pipe */ dup2(fd[WRITE], 1); /*Duplicar la terminación usada en stdout */ close(fd[WRITE]); /* Cierre terminación usada original */ execlp(argv[1], argv[1], NULL); /* Ejecución programa escritor */ perror("connect"); } else /* Hijo lector */ { close(fd[WRITE]); /* Cierre terminal no usada de la pipe */ dup2(fd[READ], 0); /* Duplicar la terminación usada en stdin */ close(fd[READ]); /* Cierre terminación usada original */ execlp(argv[2], argv[2], NULL); /* Ejecución programa lector */ perror("connect"); } } SO2/Practicas_SOII/fuentes_luisapa/prac19.c /* Sistemas Operativos II */ /* prac19.c */ /* Código del proceso padre */ #include <signal.h> #include <stdio.h> #include <unistd.h> #define MAXLINE 4096 /* max line lengh */ static void (sig_pipe(int singo)); int main() { int n; int fd1[2], fd2[2]; pid_t pid; char line[MAXLINE]; if (signal(SIGPIPE, sig_pipe) == SIG_ERR) perror("signal error"); if (pipe(fd1) < 0 || pipe(fd2) < 0) perror("pipe error"); if ((pid = fork()) < 0) perror("fork error"); else if (pid > 0) { close(fd1[0]); close(fd2[1]); while(fgets(line, MAXLINE, stdin) != NULL) { n = strlen(line); if (write(fd1[1], line, n) != n) perror("write error to pipe"); if ((n = read(fd2[0], line, MAXLINE)) < 0) perror("read error form pipe"); if (n == 0) { perror("chid close pipe"); break; } line[n] = '\0'; if (fputs(line, stdout) == EOF) perror("fputs error"); } if (ferror(stdin)) perror("fgets error on stdin"); exit(0); } else { close(fd1[1]); close(fd2[0]); if (fd1[0] != STDIN_FILENO) { if (dup2(fd1[0], STDIN_FILENO) != STDIN_FILENO) perror("dup2 error to stdin"); close(fd1[0]); } if (fd2[1] != STDOUT_FILENO) { if (dup2(fd2[1], STDOUT_FILENO) != STDOUT_FILENO) perror("dup2 error to stdout"); close(fd2[1]); } if (execl("./suma2", "suma2", 0) < 0) perror("execl error"); } } static void (sig_pipe(int signo)) { printf("SIGPIPE caught \n"); exit(1); } SO2/Practicas_SOII/fuentes_luisapa/prac19_new.c /* Sistemas Operativos II */ /* prac19.c */ /* Código del proceso padre */ #include <signal.h> #include <stdio.h> #include <unistd.h> #define MAXLINE 4096 /* max line lengh */ static void (sig_pipe(int singo)); int main() { int n; int fd1[2], fd2[2]; pid_t pid; char line[MAXLINE]; if (signal(SIGPIPE, sig_pipe) == SIG_ERR) perror("signal error"); if (pipe(fd1) < 0 || pipe(fd2) < 0) perror("pipe error"); if ((pid = fork()) < 0) perror("fork error"); else if (pid > 0) { close(fd1[0]); close(fd2[1]); while(fgets(line, MAXLINE, stdin) != NULL) { n = strlen(line); if (write(fd1[1], line, n) != n) perror("write error to pipe"); if ((n = read(fd2[0], line, MAXLINE)) < 0) perror("read error form pipe"); if (n == 0) { perror("chid close pipe"); break; } line[n] = '\0'; if (fputs(line, stdout) == EOF) perror("fputs error"); } if (ferror(stdin)) perror("fgets error on stdin"); exit(0); } else { close(fd1[1]); close(fd2[0]); if (fd1[0] != STDIN_FILENO) { if (dup2(fd1[0], STDIN_FILENO) != STDIN_FILENO) perror("dup2 error to stdin"); close(fd1[0]); } if (fd2[1] != STDOUT_FILENO) { if (dup2(fd2[1], STDOUT_FILENO) != STDOUT_FILENO) perror("dup2 error to stdout"); close(fd2[1]); } if (execl("./pr20", "pr20", 0) < 0) perror("execl error"); } } static void (sig_pipe(int signo)) { printf("SIGPIPE caught \n"); exit(1); } SO2/Practicas_SOII/fuentes_luisapa/prac2.c /* Sistemas Operativos II */ /* prac2.c */ #include <sys/types.h> #include <unistd.h> // #include <vfork.h> /* Requerido por algunos sistemas */ int main() { int glob = 6; int var = 88; pid_t pid; printf("Mensaje antes de funcion vfork \n"); if ((pid = vfork()) < 0) perror("vfork error"); else if (pid == 0) { glob++; var++; printf("pid = %d, glob = %d, var = %d \n", getpid(), glob, var); exit(0); } printf("pid = %d, glob = %d, var = %d \n", getpid(), glob, var); exit(0); } SO2/Practicas_SOII/fuentes_luisapa/prac20.c /* Sistemas Operativos II */ /* prac20.c */ #include <stdio.h> #define MAXLINE 4096 /* max line lengh */ int main() { int int1, int2; char cadena[100]; char line[MAXLINE]; /*if (setvbuf(stdin, NULL, _IOLBF, 0) != 0) perror("setvbuf error"); if (setvbuf(stdout, NULL, _IOLBF, 0) != 0) perror("setvbuf error"); */ while (fgets(line, MAXLINE, stdin) != NULL) { if (sscanf(line, "%d %d", &int1, &int2) == 2) { if (printf("%d \n", int1 + int2) == EOF) perror("printf error"); } else { if (printf("Args. Inválidos \n") == EOF) perror("printf error"); } } exit(0); } SO2/Practicas_SOII/fuentes_luisapa/prac20_new.c /* Sistemas Operativos II */ /* prac20.c */ #include <stdio.h> #define MAXLINE 4096 /* max line lengh */ int main() { int int1, int2; char cadena[100]; char line[MAXLINE]; if (setvbuf(stdin, NULL, _IOLBF, 0) != 0) perror("setvbuf error"); if (setvbuf(stdout, NULL, _IOLBF, 0) != 0) perror("setvbuf error"); while (fgets(line, MAXLINE, stdin) != NULL) { if (sscanf(line, "%d %d", &int1, &int2) == 2) { if (printf("%d \n", int1 + int2) == EOF) perror("printf error"); } else { if (printf("Args. Inválidos \n") == EOF) perror("printf error"); } } exit(0); } SO2/Practicas_SOII/fuentes_luisapa/prac21_e.c /* Sistemas Operativos II */ /* prac21_e.c */ /* Proceso escritor de named pipe denominado "miPipa" */ #include <stdio.h> #include <fcntl.h> int main() { int fd, messageLen, i; char message[100]; sprintf(message, "Hola de PID %d", getpid()); messageLen = strlen(message) + 1; do { fd = open ("miPipa", O_WRONLY); if (fd == -1) { printf("\n Error, la FIFO no existe.\n"); sleep(1); } } while (fd == -1); printf("\n OK, la FIFO ya existe.\n Enviando mensajes ...\n"); for (i = 1; i <= 3; i++) { write(fd, message, messageLen); sleep(3); } close(fd); } SO2/Practicas_SOII/fuentes_luisapa/prac21_l.c /* Sistemas Operativos II */ /* prac21_l.c */ /* Proceso lector de named pipe denominado "miPipa" */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int readLine(int fdaux, char *straux); int main() { int fd; char str[100]; unlink("miPipa"); mknod("miPipa", S_IFIFO, 0); chmod("miPipa", 0770); fd = open ("miPipa", O_RDONLY); while (readLine(fd, str) > 0) printf("%s\n", str); close(fd); } int readLine(int fdaux, char *straux) { int n; do { n = read(fdaux, straux, 1); } while (n > 0 && *straux++ != NULL); return (n); } SO2/Practicas_SOII/fuentes_luisapa/prac22.c /* Sistemas Operativos II */ /* prac22.c */ #include <unistd.h> #include <signal.h> /* Requerida por pause */ static void sig_usr(int signo); /* one handler for both signal */ int main() { if (signal(SIGUSR1, sig_usr) == SIG_ERR) { perror("can't catch SIGUSR1"); exit(1); } if (signal (SIGUSR2, sig_usr) == SIG_ERR) { perror("can´t catch SIGUSR2"); exit(1); } while (1) pause(); } static void sig_usr(int signo) { if (signo == SIGUSR1) printf("received SIGUSR1 \n"); else if (signo == SIGUSR2) printf("received SIGUSR2 \n"); else { printf("recieved signal %d \n", signo); exit(1); } return; } SO2/Practicas_SOII/fuentes_luisapa/prac23.c /* Sistemas Operativos II */ /* prac23.c */ #include <pwd.h> #include <unistd.h> #include <signal.h> static void my_alarm(); int main() { int cuenta = 0; struct passwd *ptr; signal(SIGALRM, my_alarm); alarm(1); while (1) { cuenta++; if ((ptr = getpwnam("luisapa")) == NULL) { perror("getpwnam error"); // exit(1); } else if (strcmp(ptr->pw_name, "luisapa") != 0) { printf("return value corrupted !, pw_name = %s | cuenta %d \n", ptr->pw_name, cuenta); cuenta = 0; } } } static void my_alarm() { struct passwd *rootptr; signal(SIGALRM, my_alarm); printf("in signal handler \n"); if ((rootptr = getpwnam("root")) == NULL) { perror("gerpwnam(root) error"); exit(1); } alarm(1); return; } SO2/Practicas_SOII/fuentes_luisapa/prac24.c /* Sistemas Operativos II */ /* prac24.c */ #include <sys/types.h> #include <stdio.h> #include <signal.h> static void sig_cld(); int main() { pid_t pid; if (signal(SIGCHLD, sig_cld) == -1) perror ("signal error"); if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) { sleep(2); _exit(0); } pause(); exit(0); } static void sig_cld() { pid_t pid; int status; printf("SIGCHLD received \n"); if (signal(SIGCHLD, sig_cld) == -1) perror("signal error"); if ((pid = wait(&status)) < 0) perror("wait error"); printf("pid = %d \n", pid); return; } SO2/Practicas_SOII/fuentes_luisapa/prac25.c /* Sistemas Operativos II */ /* prac25.c */ #include <stdio.h> #include <unistd.h> #include <signal.h> static void sig_alrm(); unsigned int sleep2(unsigned int nsecs); int main() { printf("Acabo de emperzar y me voy a dormir \n"); sleep2(10); printf("Me acabo de despertar \n"); exit(0); } static void sig_alrm() { printf("Estoy en el signal hadler\n"); return; } unsigned int sleep2(unsigned int nsecs) { printf("Estoy en sleep2 \n"); if(signal (SIGALRM, sig_alrm) == SIG_ERR) return(nsecs); alarm(nsecs); /* start the timer */ pause(); /* next caught signal wakes us up */ printf("Salgo de sleep2 \n"); return(alarm(0)); /* turn off timer, return unslept time */ } SO2/Practicas_SOII/fuentes_luisapa/prac26.c /* Sistemas Operativos II */ /* prac26.c */ #include <stdio.h> #include <unistd.h> #include <signal.h> #define MAXLINE 4096 static void sig_alrm(); int main() { int n; char line[MAXLINE]; if (signal(SIGALRM, sig_alrm) == SIG_ERR) { perror("signal(SIGALRM) error"); exit(1); } alarm(10); if ((n = read(STDIN_FILENO, line, MAXLINE)) < 0) { perror("read error"); exit(1); } alarm(0); write(STDOUT_FILENO, line, n); exit(1); } static void sig_alrm() { printf("\n Estoy en el hadler\n"); return; } SO2/Practicas_SOII/fuentes_luisapa/prac3.c /* Sistemas Operativos II */ /* prac3.c */ #include <sys/types.h> #include <sys/wait.h> void pr_exit(int estado); int main() { pid_t pid; int status; if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) exit(7); if (wait(&status) != pid) perror("wait error"); pr_exit(status); if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) abort(); if (wait(&status) != pid) perror("wait error"); pr_exit(status); if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) status = status / 0; if (wait(&status) != pid) perror("wait error"); pr_exit(status); exit(0); } void pr_exit(int estado) { if (WIFEXITED(estado)) printf("Terminación normal, exit status = %d\n", WEXITSTATUS(estado)); else if (WIFSIGNALED(estado)) { printf("Terminación anormal, numero de signal = %d ", WTERMSIG(estado)); if (WCOREDUMP(estado)) printf("(se genero fichero core)\n"); else printf(" \n"); } else if (WIFSTOPPED(estado)) printf("Hijo detenido, numero de signal = %d\n", WSTOPSIG(estado)); } SO2/Practicas_SOII/fuentes_luisapa/prac3_1.c /* Sistemas Operativos II */ /* prac3.c */ #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> void pr_exit(int estado); int main() { pid_t pid; int status; if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) exit(7); if (wait(&status) != pid) perror("wait error"); pr_exit(status); if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) abort(); if (wait(&status) != pid) perror("wait error"); pr_exit(status); if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) status = status / 0; if (wait(&status) != pid) perror("wait error"); pr_exit(status); printf("\n Prueba hijos STOPPED \n"); fflush(stdout); if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) { sleep(40); kill (getpid(), SIGSTOP); exit(11); } if (waitpid(pid, &status, WUNTRACED) != pid) perror("waitpid error"); pr_exit(status); printf("\n Envía señal SIGCONT o señal de Fin al proceso PDI: %d \n", pid); fflush(stdout); if (wait(&status) != pid) perror("wait error"); pr_exit(status); exit(0); } void pr_exit(int estado) { if (WIFEXITED(estado)) printf("Terminación normal, exit status = %d\n", WEXITSTATUS(estado)); else if (WIFSIGNALED(estado)) { printf("Terminación anormal, numero de signal = %d ", WTERMSIG(estado)); if (WCOREDUMP(estado)) printf("(se genero fichero core)\n"); else printf(" \n"); } else if (WIFSTOPPED(estado)) printf("Hijo detenido, numero de signal = %d\n", WSTOPSIG(estado)); } SO2/Practicas_SOII/fuentes_luisapa/prac4_1.c /* Sistemas Operativos II */ /* prac4_1.c */ #include <sys/types.h> #include <stdlib.h> int main() { pid_t pid; if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) exit(0); sleep(4); system("ps -l"); exit(0); } SO2/Practicas_SOII/fuentes_luisapa/prac4_2.c /* Sistemas Operativos II */ /* prac4_2.c */ #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main() { pid_t pid; if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) { if ((pid = fork()) < 0) perror("fork error"); else if (pid > 0) exit(0); sleep(2); printf("Second child, parent pid = %d \n", getppid()); exit(0); } if (waitpid(pid, NULL, 0) != pid) perror("waitpid error"); exit(0); } SO2/Practicas_SOII/fuentes_luisapa/prac5.c /* Sistemas Operativos II */ /* prac5.c */ #include <sys/types.h> #include <stdio.h> void charatatime(char *str); int main() { pid_t pid; if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) charatatime("salida del hijo \n"); else charatatime("salida del padre \n"); exit(0); } void charatatime(char *str) { char *ptr; int c; setbuf(stdout, NULL); ptr = str; do { c = *ptr; putc(c, stdout); } while (*ptr++ != '\0'); } SO2/Practicas_SOII/fuentes_luisapa/prac6_1.c /* Sistemas Operativos II */ /* prac6_1.c */ #include <stdio.h> int main(int argc, char *argv[]) { int i; char **ptr; extern char **environ; for (i = 0; i < argc; i++) printf("argv[%d]: %s \n", i, argv[i]); ptr = environ; while (*ptr != NULL) { printf("%s \n", *ptr); ptr++; } exit(0); } SO2/Practicas_SOII/fuentes_luisapa/prac6_2.c /* Sistemas Operativos II */ /* prac6_2.c */ #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main() { char *env_init[] = {"USER=unknown", "PATH=/tmp", NULL}; pid_t pid; printf("\n Inicio del primer hijo \n\n"); fflush(stdout); if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) { if (execle("/export/home0/practicas/atc/soii/echoall", "echoall", "my arg1", "MY ARG2", (char *) 0, env_init) < 0) perror("execle error"); } if (waitpid (pid, NULL, 0) < 0) perror("wait error"); printf("\n\n Finalización del primer hijo \n\n\n"); printf("\n Inicio del segundo hijo \n\n"); fflush(stdout); if ((pid = fork()) < 0) perror("fork error"); else if (pid == 0) { if (execlp("echoall", "echoall", "only 1 arg", (char *) 0) < 0) perror("execlp error"); } if (waitpid (pid, NULL, 0) < 0) perror("wait error"); printf("\n\n Finalización del segundo hijo \n\n\n"); fflush(stdout); exit(0); } SO2/Practicas_SOII/fuentes_luisapa/prac7.c /* Sistemas Operativos II */ /* prac7.c */ #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> void pr_exit(int estado); int main(int argc, char *argv[]) { int status; if (argc < 2) { perror("Se requiere como argumento una línea de orden"); exit(1); } if ((status = system(argv[1])) < 0) perror ("system() error"); pr_exit(status); exit(0); } void pr_exit(int estado) { if (WIFEXITED(estado)) printf("Terminación normal, exit status = %d\n", WEXITSTATUS(estado)); else if (WIFSIGNALED(estado)) { printf("Terminación anormal, numero de signal = %d ", WTERMSIG(estado)); if (WCOREDUMP(estado)) printf("(se genero fichero core)\n"); else printf(" \n"); } else if (WIFSTOPPED(estado)) printf("Hijo detenido, numero de signal = %d\n", WSTOPSIG(estado)); } SO2/Practicas_SOII/fuentes_luisapa/prac9.c /* Sistemas Operativos II */ /* prac9.c */ #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <errno.h> int mi_system(char *cmdstring); void pr_exit(int estado); int main() { int status; if ((status = mi_system("date")) < 0) perror("system() error"); pr_exit(status); if ((status = mi_system("nosuchcommand")) < 0) perror("system() error"); pr_exit(status); if ((status = mi_system("who; exit 44")) < 0) perror("system() error"); pr_exit(status); exit(0); } void pr_exit(int estado) { if (WIFEXITED(estado)) printf("Terminacion normal, exit status = %d\n", WEXITSTATUS(estado)); else if (WIFSIGNALED(estado)) { printf("Terminacion anormal, numero de signal = %d ", WTERMSIG(estado)); if (WCOREDUMP(estado)) printf("(se genero fichero core)\n"); else printf(" \n"); } else if (WIFSTOPPED(estado)) printf("Hijo detenido, numero de signal = %d\n", WSTOPSIG(estado)); } SO2/Practicas_SOII/fuentes_luisapa/servidRPC.c /* Luis C. Aparicio Sistemas Operativos Área de Arquitectura y Tecnología de computadores Funciones RPC del servidor para la suma y resta de dos enteros servidRPC.c */ #include "calcular.h" int *sumar_1_svc(int a, int b, struct svc_req *rqstp) { static int r; r = a + b; return(&r); } int *restar_1_svc(int a, int b, struct svc_req *rqstp) { static int r; r = a - b; return(&r); } SO2/Practicas_SOII/fuentes_luisapa/servTCP.c /* Luis C. Aparicio Sistemas Operativos Área de Arquitectura y Tecnología de computadores Programa servidor de suma utilizando sockets stream (TCP) servTCP.c */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> int main() { struct sockaddr_in server_addr, client_addr; int sd, sc, salir; int size, res; int num[2]; sd = socket(AF_INET, SOCK_STREAM, 0); /* Asigna la dirección al socket */ bzero((char *)&server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(5500); bind(sd, &server_addr, sizeof(server_addr)); listen(sd, 5); size = sizeof(client_addr); salir = 0; while (salir == 0) { printf("Esperando conexión en el puerto: 5500\n"); fflush(stdout); sc = accept(sd, (struct sockaddr *)&client_addr, &size); if(sc < 0) salir = 1; else { /* recibe la petición, dos número enteros */ //read(sc, (char*) num, 2*sizeof(int)); read(sc, &num, 2*sizeof(int)); res = num[0] + num[1]; printf("\nServicio: %d + %d = %d \n", num[0], num[1], res); fflush(stdout); /* envía el resultado y cierra la conexión */ //write(sc, (char*)&res, sizeof(int)); write(sc, &res, sizeof(int)); close (sc); } } printf("\n Error en accept \n"); fflush(stdout); close(sd); exit(0); } SO2/Practicas_SOII/fuentes_luisapa/servUDP.c /* Luis C. Aparicio Sistemas Operativos EUPT: Área de Arquitectura y Tecnología de computadores Programa servidor de suma utilizando sockets datagram (UDP) servUDP.c */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> int main() { struct sockaddr_in server_addr, client_addr; int sd; int size, res; int num[2]; sd = socket(AF_INET, SOCK_DGRAM, 0); /* Asigna la dirección al socket */ bzero((char *)&server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(4400); bind(sd, (struct sockaddr *)&server_addr, sizeof(server_addr)); size = sizeof(client_addr); while (1) { printf("\nEsperando conexión en el puerto: 4400"); fflush(stdout); //recvfrom (sd, (char*) num, 2 * sizeof(int), 0, (struct sockaddr *)&client_addr, &size); recvfrom (sd, num, 2 * sizeof(int), 0, (struct sockaddr *)&client_addr, &size); res = num[0] + num[1]; printf("\nServicio: %d + %d = %d \n", num[0], num[1], res); fflush(stdout); /* Envía la petición al cliente. La estructura client_addr contiene la dirección del socket del cliente */ //sendto(sd, (char*)&res, sizeof(int), 0, (struct sockaddr *)&client_addr, size); sendto(sd, &res, sizeof(int), 0, (struct sockaddr *)&client_addr, size); } } SO2/Practicas_SOII/fuentes_luisapa/suma2.c /* Sistemas Operativos II */ /* suma2.c */ /* Código del filtro que actua como coproceso */ /* Lee dos enteros de la entrada estandard y devuelve su suma por la salida estándar */ #include <stdio.h> #include <unistd.h> #define MAXLINE 4096 /* max line lengh */ int main() { int n, int1, int2; char line[MAXLINE]; char c; while ((n = read(STDIN_FILENO, line, MAXLINE)) > 0) { line[n] = '\0'; if (sscanf(line, "%d %d", &int1, &int2) == 2) { sprintf(line, "%d \n", int1 + int2); n = strlen(line); if (write(STDOUT_FILENO, line, n) != n) perror("Error de escritura"); } else { if (write(STDOUT_FILENO, "Args. no válidos \n", 18) != 18) perror("Error de escritura"); } } exit(0); } SO2/Practicas_SOII/operativos.c Problema2.c #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> //NOTA: Para unix la estructura cambia union semun{ int val; /*Para SETVAL*/ struct semid_ds *buf; /*buffer para IPC_STAT y IPC_SET*/ unsigned short int *array; /*array para GETALL, SETALL*/ struct seminfo *_buf; /*buffer para IPC_INFO*/ }arg; int main(){ int id_semaforo; //manejador del vector de semaforos int key = 5; //Clave numerica que identifica al vector de semaforos int cant_sem = 5; // Numero de semaforos a crear int i,valor; /* la funcion semget, crea un vector se semaforos. 1 argumento: Clave numerica que identifica al vector de semaforos 2 argumento: Numero de semaforos que se quieren crear 3 argumento: Permisos del conjunto de semaforos */ printf("\nParte A: Creo un vector con %d semaforos\n", cant_sem); fflush(stdout); if((id_semaforo = semget(key, cant_sem, IPC_CREAT|0666))!=-1){ printf("El identificador del vector de semaforos es %d\n\n", id_semaforo); printf("Parte B: Inicializo cada semaforo\n"); i = 0; /* La funcion semctl, inicializa los semaforos 1 argumento: Es el numero del vector que contiene los semaforos 2 argumento: Es el indice del semaforo, dentro de vector. 3 argumento: Comando a ejecutar. 4 argumeto: Puede estar o no, si esta, ira acorde con el tercer argumento. */ for(i = 0; i < cant_sem; i++){ printf("Inicializo el semaforo nº %d\n", i); arg.val = 1; semctl(id_semaforo, i, SETVAL, arg); } printf("\n"); fflush(stdout); printf("Parte C: Enseño los valores de cada semaforo\n"); for(i = 0; i < cant_sem; i++){ printf("Muestro el valor del semaforo nº %d, su valor es: \n", i); valor = semctl(id_semaforo, i, GETVAL); printf("%d\n", valor); } printf("Preparando el resto de la ejecucion...\n\n"); }else{ printf("ERROR: No se ha podido crear el semaforo\n"); exit(1); } } Filosofos.c #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <errno.h> union semun{ int val; /*Para SETVAL*/ struct semid_ds *buf; /*buffer para IPC_STAT y IPC_SET*/ unsigned short int *array; /*array para GETALL, SETALL*/ struct seminfo *_buf; /*buffer para IPC_INFO*/ }arg; void op_signal(int sem, int n); void op_wait(int sem, int n); int main(int argc, char *argv[]){ int i, valor_aux, pos_filosofo, tiempo_pensamiento; int id_semaforo; // Variable donde recogemos el identificador del semaforo int key = 5; // Clave que identifica al vector de los semaforos. int cant_sem = 5; // Numero de semaforos que tiene el vector de semaforos. int valor; // En este caso son los palillos chinos. pos_filosofo = (atoi(argv[1])); tiempo_pensamiento = (atoi(argv[2])); if ((id_semaforo = semget(key, cant_sem, 0)) != -1){ while(1){ printf("El filosofo %d esta PENSANDO\n\n", pos_filosofo); fflush(stdout); sleep(tiempo_pensamiento); //El sleep, se introduce para simular, que el filosofo esta pensando, se intenta //que el tiempo de pensamiento para todos los filosofos no sea el mismo //Asi es mas divertido :) //Ejecucion asimetrica if(pos_filosofo % 2 == 0){//La posicion es PAR printf("El filosofo %d esta EMPEZANDO A COMER\n\n", pos_filosofo); op_wait(id_semaforo, pos_filosofo); op_wait(id_semaforo, ((pos_filosofo + 1) % 5)); //Sleep para que lo filosofos coman. sleep(tiempo_pensamiento); printf("El filosofo %d esta TERMINANDO DE COMER\n\n", pos_filosofo); fflush(stdout); }else{//Si es impar //printf("\n pos: %d | pos + 1: %d",pos_filosofo, (pos_filosofo + 1)%5 ); // fflush(stdout); op_wait(id_semaforo, ((pos_filosofo + 1) % 5)); op_wait(id_semaforo, pos_filosofo); printf("El filosofo %d esta EMPEZANDO A COMER\n\n", pos_filosofo); fflush(stdout); for(i = 0; i < 5; i++){ valor = semctl(id_semaforo, i, GETVAL); } //Sleep para que lo filosofos coman. sleep(tiempo_pensamiento); printf("El filosofo %d esta TERMINANDO DE COMER\n\n", pos_filosofo); fflush(stdout); } op_signal(id_semaforo, pos_filosofo); op_signal(id_semaforo, ((pos_filosofo + 1) % 5)); } }else{ printf("La llamada semget ha fallado su valor es -1\n"); } exit(0); } void op_signal(int sem, int n){ int valor_semop_signal = 0; struct sembuf sop; /*Construir un elemento de vector de operaciones*/ sop.sem_num = n; sop.sem_op = 1; /*Operacion signal o liberar una copia recurso*/ sop.sem_flg = 0; valor_semop_signal = semop(sem, &sop, 1); /*Operacion signal propiamente dicha*/ if(valor_semop_signal == -1){ printf("ERROR:El valor de semop es -1 en signal\n"); }//else{ //printf("El valor de semop es %d\n", valor_semop_signal); //} } void op_wait(int sem, int n){ int valor_semop_wait = 0; struct sembuf sop; /*Construir un elemento de vectos de operaciones*/ sop.sem_num = n; sop.sem_op = -1; /*Operacion wait u obtencion una copia recurso*/ sop.sem_flg = 0; valor_semop_wait = semop(sem, &sop, 1); /*Operacion wait propiamente dicha*/ if(valor_semop_wait == -1){ printf("ERROR: El valor de semop en wait es -1\n"); }//else{ //printf("El valor de semop es %d\n", valor_semop_wait); //} } Prueba_filosofos.sh #!/bin/bash ./problema2 ./filosofos 0 1 & ./filosofos 1 1 & ./filosofos 2 1 & ./filosofos 3 1 & ./filosofos 4 1 & 4 FILOSOFOS SE SIENTAN A LA MESA Y UNO SE QUEDA FUERA Creasem.c /* * Programa que crea un vector de semaforos * para el problema de los filósofos. * */ #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <stdio.h> int main() { union semun { int val; struct semid_ds *buf; ushort *array; } arg; int semid; int key = 125; int numsem = 6; int tenedor; ushort valtenedor[6] = {1,1,1,1,1,4}; //borramos semaforos preexistentes if ((semid = semget(key, numsem, 0)) != -1) { semctl(semid, 0, IPC_RMID); } //creamos vector de semaforos if ((semid = semget(key, numsem, IPC_CREAT | 0600)) != -1) { //inicializamos semaforo objetos /*arg.val = 1; for (tenedor = 0; tenedor < 5; tenedor++) { semctl(semid, tenedor, SETVAL, arg); } */ arg.array = valtenedor; semctl(semid, 0, SETALL, arg); } //Comprobamos que las inicializaciones son correctas // for (tenedor = 0; tenedor < 6; tenedor++) { // printf("TENEDOR %d = %d \n", tenedor, semctl(semid, tenedor, GETVAL)); // } // /* semctl(semid, 0, GETALL, arg); for (tenedor = 0; tenedor < 5; tenedor++) { printf("TENEDOR %d = %d \n", tenedor, arg.array[tenedor]); }*/ return(0); } Filosofo.c #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <stdio.h> void op_wait(int sem, int n); void op_signal(int sem, int n); void comer(int n, int numfilosofo); void pensar(int n, int numfilosofo); int main(int argc, char* argv[]) { int semid; int key = 125; int numsem = 6; int tiempo; int numfilosofo; tiempo = atoi(argv[2]); numfilosofo = atoi(argv[1]); semid = semget(key, numsem, 0); while(1) { pensar(tiempo, numfilosofo); op_wait(semid,5); printf("El filosofo %d se sienta en la mesa\n", numfilosofo); fflush(stdout); op_wait(semid, numfilosofo); op_wait(semid, (numfilosofo + 1) % 5 ); comer(tiempo, numfilosofo); op_signal(semid, numfilosofo); op_signal(semid, (numfilosofo + 1) % 5 ); printf("El filosofo %d se levanta de la mesa\n", numfilosofo); fflush(stdout); op_signal(semid, 5); } } void op_wait(int sem, int n) { struct sembuf sop; /* Construir un elemento de vector de operaciones */ sop.sem_num = n; sop.sem_op = -1; /* Operación wait u obtención una copia recurso */ sop.sem_flg = 0; semop(sem, &sop, 1); /* Operación wait propiamente dicha */ } void op_signal(int sem, int n) { struct sembuf sop; /* Construir un elemento de vector de operaciones */ sop.sem_num = n; sop.sem_op = 1; /* Operación signal o liberar una copia recurso */ sop.sem_flg = 0; semop(sem, &sop, 1); /* Operación signal propiamente dicha */ } void comer(int n, int numfilosofo) { printf("\nFilosofo %d empezando a comer...\n", numfilosofo); fflush(stdout); sleep(n); printf("\nFilosofo %d terminando de comer...", numfilosofo); fflush(stdout); } void pensar(int n, int numfilosofo) { printf("Filosofo %d pensando...\n", numfilosofo); fflush(stdout); sleep(n); } LECTOR ESCRITOR VERSIÓN 2. Lec_esc_inicializar.c #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/sem.h> #include <sys/ipc.h> #include <sys/types.h> //#define key_t key; int crear_sem(int key, int num_sem); int inicializar_sem(int manejador, int componente, int valor_sem); int valor_sem (int semid, int pos); void op_wait(int semid, int pos); void op_signal(int semid, int pos); int main(int argc,char *argv[]){ int semid, num_sem, clave; if (argc != 3) { printf("Error en el numero de argumentos, [clave, num_sem] \n"); exit(0); }else{ //obtengo los valores pasados como argumento por consola clave = atoi(argv[1]); //clave 578557 num_sem = atoi(argv[2]); int num_lectores = 3; semid = crear_sem(clave, num_sem); inicializar_sem(semid, 0, 1); //mutex=1 inicializar_sem(semid, 1, num_lectores); //lectores = Num_lectores printf("Se ha creado el semaforo con identificador %d para el problema lector-escritor correctamente \n", semid); fflush(stdout); } } int crear_sem(int key, int num_sem){ int manejador= 0 ; manejador = semget(key, num_sem, IPC_CREAT | 0600); //semget devuelve el manejador que identifica al semaforo if (manejador >=0 ){ //si se ha creado correctamente el identif del sem sera 0 o mayor de cero printf("Se ha creado correctamente un vector de semaforos con %d componentes \n", num_sem); printf("Ha sido creado correctamente el semaforo con clave= %d\n", key); fflush(stdout); return(manejador); }else{ printf("Error al crear el semaforo con clave %d\n ", key); exit(1); } } int inicializar_sem(int manejador, int componente, int valor_sem){ union semun{ int val; //para SETVAL struct semid_ds *buf; //IPC_STAT y IPC_SET unsigned short int *array; //GETALL y SETALL struct seminfo *__buf; } semctl_arg; semctl_arg.val = valor_sem; if(semctl(manejador, componente, SETVAL, semctl_arg) == 0) { printf("Se ha inicializado correctamente a %d la componente %d del semaforo %d\n", valor_sem, componente, manejador); fflush(stdout); return(0); }else{ printf("Error al inicializar la componente %d del semaforo %d\n", componente, manejador); fflush(stdout); return(-1); } } int valor_sem (int semid, int pos){ int val_sem; union semun { int val; /* valor para SETVAL */ struct semid_ds *buf; /* buffer para IPC_STAT, IPC_SET */ unsigned short int *array; /* array para GETALL, SETALL */ struct seminfo *__buf; /* buffer para IPC_INFO */ } semctl_arg; val_sem= semctl(semid, pos, GETVAL, semctl_arg); if (val_sem <0) { fflush(stdout); exit(0); }else{ return (val_sem); } } Lector.c #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/sem.h> #include <sys/ipc.h> #include <sys/types.h> #include <unistd.h> void op_wait(int semid, int pos); void op_signal(int semid, int pos); int valor_sem (int semid, int pos); union semun { int val; /* valor para SETVAL */ struct semid_ds *buf; /* buffer para IPC_STAT, IPC_SET */ unsigned short int *array; /* array para GETALL, SETALL */ struct seminfo *__buf; /* buffer para IPC_INFO */ } semctl_arg; int main (int argc, char *argv[]) { int clave, num_lector, tiempo, semid; if (argc != 4) { printf("Error en el lector"); exit(0); }else{ /* mutex=0 * lectores=1 */ num_lector =atoi(argv[1]); clave =atoi(argv[2]); tiempo =atoi(argv[3]); int iteraciones = 5; int j= 0; semid = semget(clave, 2, 0); //accedo al semaforo while (j < iteraciones) { printf("LECTOR %d: INTENTO \n",num_lector); fflush(stdout); op_wait(semid, 0); //wait(mutex) op_wait(semid, 1); //wait(lectores) op_signal(semid, 0); //signal(mutex) printf("LECTOR %d: LEYENDO \n",num_lector); fflush(stdout); sleep(tiempo); op_signal(semid, 1); //signal(lectores) printf("LECTOR %d: FIN \n",num_lector); fflush(stdout); j++; } } } int valor_sem (int semid, int pos){ int val_sem; union semun { int val; /* valor para SETVAL */ struct semid_ds *buf; /* buffer para IPC_STAT, IPC_SET */ unsigned short int *array; /* array para GETALL, SETALL */ struct seminfo *__buf; /* buffer para IPC_INFO */ } semctl_arg; //int posi; val_sem= semctl(semid, pos, GETVAL, semctl_arg); if (val_sem <0) { exit(0); }else{ return (val_sem); } } void op_wait(int semid, int pos){ struct sembuf sop; //estructura menejo de operaciones sobre el semaforo /*Inicializar valores*/ sop.sem_num= pos; sop.sem_op= -1; sop.sem_flg= 0; /* Ejecución de una operación Down sobre sem_id: */ semop(semid,&sop,1); } void op_signal(int semid, int pos){ struct sembuf sop; //estructura menejo de operaciones sobre el semaforo /*Inicializar valores*/ sop.sem_num= pos; sop.sem_op= 1; sop.sem_flg= 0; /* Ejecución de una operación Up sobre sem_id: */ semop(semid,&sop,1); } Escritor.c #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/sem.h> #include <sys/ipc.h> #include <sys/types.h> #include <unistd.h> void op_wait(int semid, int pos); void op_signal(int semid, int pos); int valor_sem (int semid, int pos); int main (int argc, char *argv[]) { int clave, num_escritor, tiempo, semid, i; if (argc != 4) { printf("Error en el escritor"); exit(0); }else{ num_escritor =atoi(argv[1]); clave =atoi(argv[2]); tiempo =atoi(argv[3]); int iteraciones = 5; int j=0; semid = semget(clave, 2, 0); //accedo al semaforo while (j < iteraciones) { printf("ESCRITOR %d: INTENTO\n",num_escritor); fflush(stdout); op_wait(semid, 0); //wait(mutex) for (i=1; i<=3; i++) { op_wait(semid, 1); //wait(lectores) } printf("ESCRITOR %d: ESCRIBIENDO\n",num_escritor); fflush(stdout); sleep(tiempo); for (i=1; i<=3; i++) { op_signal(semid, 1); //signal(lectores) } op_signal(semid, 0); //signal(mutex) printf("ESCRITOR %d: FIN\n",num_escritor); fflush(stdout); j++; } } } int valor_sem (int semid, int pos){ int val_sem; union semun { int val; /* valor para SETVAL */ struct semid_ds *buf; /* buffer para IPC_STAT, IPC_SET */ unsigned short int *array; /* array para GETALL, SETALL */ struct seminfo *__buf; /* buffer para IPC_INFO */ } semctl_arg; val_sem= semctl(semid, pos, GETVAL, semctl_arg); if (val_sem <0) { fflush(stdout); exit(0); }else{ return (val_sem); } } void op_wait(int semid, int pos){ struct sembuf sop; //estructura menejo de operaciones sobre el semaforo /*Inicializar valores*/ sop.sem_num= pos; sop.sem_op= -1; sop.sem_flg= 0; /* Ejecución de una operación Down sobre sem_id: */ semop(semid,&sop,1); } void op_signal(int semid, int pos){ struct sembuf sop; //estructura menejo de operaciones sobre el semaforo /*Inicializar valores*/ sop.sem_num= pos; sop.sem_op= 1; sop.sem_flg= 0; /* Ejecución de una operación Up sobre sem_id: */ semop(semid,&sop,1); } Lanzar_lect_escritor.sh #!/bin/sh gcc -O2 -o lec_esc_inicializar lec_esc_inicializar.c gcc -O2 -o lector lector.c gcc -O2 -o escritor escritor.c # inicializo un semaforo con clave 578557 y componenetes ./lec_esc_inicializar 578557 2 ./escritor 1 578557 2 & #num_lector, clave, tiempo ./escritor 2 578557 2 & ./escritor 3 578557 2 & ./lector 1 578557 2 & ./lector 2 578557 2 & ./lector 3 578557 2 & PRODUCTOR CONSUMIDOR Inicioprodcons.c #include <sys/types.h> #include <string.h> #define MUTEX 0 #define HUECOS 1 #define OBJETOS 2 #define MAX_BUFFER 10 #define VALORINICIAL 5 union semun{ int val; struct semid_ds *buf; ushort *array; }arg; int main(int argc, char *argv[]){ //union semun arg; int semid, i , control; int key = atoi(argv[1]); int nsems = atoi(argv[2]); //semid = semget(key, nsems, IPC_CREAT|0600); if((semid = semget(key, nsems, MUTEX)) != -1) // Obtengo el manejador en modo uso (0) semctl(semid, MUTEX, IPC_RMID); // Borro el anterior conjunto de semaforos if((semid = semget(key, nsems, IPC_CREAT|0600)) != -1){ arg.val = 1; //Inicializo MUTEX a 1 semctl(semid,MUTEX,SETVAL,arg); arg.val = 5; //Inicializo HUECOS a 5 semctl(semid, HUECOS, SETVAL, arg); arg.val= 5; //Inicializo OBJETOS a 5 semctl(semid,OBJETOS,SETVAL,arg); } control = semctl(semid,MUTEX,SETVAL,arg); printf("Control del semaforo mutex:%d\n", control); fflush(stdout); control = semctl(semid,HUECOS,GETVAL); printf("VALOR del semaforo huecos:%d\n", control); fflush(stdout); control = semctl(semid,OBJETOS,GETVAL); printf("VALOR del semaforo objetos:%d\n", control); fflush(stdout); printf("\nFIN Inicializacion\n");fflush(stdout); //exit(0); } Productor.c #include <sys/types.h> #define MUTEX 0 #define HUECOS 1 #define OBJETOS 2 #define KEY 123 #define MAX_BUFFER 10 union semun{ int val; struct semid_ds *buf; ushort *array; } arg; void op_wait(int sem, int n); void op_signal(int sem, int n); int main(int argc, char *argv[]){ // union semun arg; int semid; int nsems = 3; int numprod, key, delay; int huecos, objetos; key = atoi(argv[1]); numprod = atoi(argv[2]); delay = atoi(argv[3]); semid = semget(key, nsems, MUTEX); if(semid == -1){ printf("\nHa ocurrido un error al acceder al semaforo.");fflush(stdout); } printf("\nProductor %d manejador del semaforo:%d\n",numprod, semid);fflush(stdout); while (1){ //printf("\n");fflush(stdout); sleep(delay); if (semctl(semid,HUECOS,GETVAL,arg)>0) { op_wait(semid, HUECOS); //wait(huecos) huecos = semctl(semid,HUECOS,GETVAL,arg); //Se obtienen los huecos op_wait(semid, MUTEX); //wait(mutex) op_signal(semid, MUTEX); //signal(mutex) op_signal(semid, OBJETOS); //signal(objetos) objetos = semctl(semid,OBJETOS,GETVAL,arg); //Se obtiene los objetos printf("\nProductor %d añade un objeto, Objetos:%d, Huecos:%d\n",numprod, objetos,huecos); fflush(stdout); }else { printf("Productor %d, NO HAY HUECOS, NO PUEDO PRODUCIR\n",numprod); fflush(stdout); } } } void op_wait(int sem, int n){ struct sembuf sop; sop.sem_num = n; sop.sem_op = -1; sop.sem_flg = 0; semop(sem, &sop,1); } void op_signal(int sem, int n){ struct sembuf sop; sop.sem_num = n; sop.sem_op = 1; sop.sem_flg = 0; semop(sem, &sop,1); } Consumidor.c #include <sys/types.h> #include <stdio.h> #define MUTEX 0 #define HUECOS 1 #define OBJETOS 2 #define MAX_BUFFER 10 union semun { int val; // Value for SETVAL struct semid_ds *buf; // Buffer for IPC_STAT, IPC_SET unsigned short *array; // Array for GETALL, SETALL struct seminfo *__buf; // Buffer for IPC_INFO (Linux-specific) }arg; void op_signal(int sem, int n); void op_wait(int sem, int n); int main(int argc, char *argv[]){ // union semun arg; int semid; int nsems = 3; int numcons, key, delay; int objetos, huecos; key = atoi(argv[1]); numcons = atoi(argv[2]); delay = atoi(argv[3]); semid = semget(key, nsems, MUTEX); if(semid == -1){ printf("\nHa ocurrido un error al acceder al semaforo."); fflush(stdout); } printf("Consumidor %d manejador del semaforo:%d\n", numcons, semid);fflush(stdout); while (1){ sleep(delay); if (semctl(semid,OBJETOS,GETVAL,arg)>0) { op_wait(semid, OBJETOS); objetos = semctl(semid,OBJETOS,GETVAL,arg); //Obtiene el valor del semaforo 2 op_wait(semid, MUTEX); op_signal(semid, MUTEX); //signal(mutex) op_signal(semid, HUECOS); //signal(huecos) huecos = semctl(semid,HUECOS,GETVAL,arg); //Obtiene el valor del semaforo 1 printf("Consumidor %d, quita un objeto. Objetos:%d, Huecos:%d\n",numcons, objetos, huecos); fflush(stdout); }else { printf("Consumidor %d, NO HAY OBJETOS, NO PUEDO CONSUMIR\n",numcons); fflush(stdout); } } } void op_signal(int sem, int n){ struct sembuf sop; sop.sem_num = n; sop.sem_op = 1; sop.sem_flg = 0; semop(sem, &sop,1); } void op_wait(int sem, int n){ struct sembuf sop; sop.sem_num = n; sop.sem_op = -1; sop.sem_flg = 0; semop(sem, &sop,1); } Prodcons.sh #!/bin/bash ./inicioprodcons 123 3 ##inicioprodcons KEY NumeroSems ./productor 123 1 2 & ##productor
Compartir