#include #include #include #include #include #include #include #define ESPERA 1000 // Son los microsegundos de espera usados para asegurar // la finalización del quantum. /********************************************************************** * * PROBAR EL SISTEMA CON Y SIN LAS OPERACIONES P Y V * **********************************************************************/ main() { int pid; /* identifica el proceso hijo */ int mutex; /* semaforo binario */ mutex=inicia(1); if (0==(pid=fork())) proceso_hijo(mutex); else proceso_padre(mutex); borra_s(mutex); } /********************************************************************** * * Tanto el proceso hijo como el padre escriben 30 secuencias de 80 caracteres * **********************************************************************/ proceso_hijo(critica) int critica; { /* escribe 30 ristras de 80 caracteres '+' */ int i,j; for (i=0;i< 30; i++) { P(critica); for (j=0; j<80; j++) { printf("+"); fflush(stdout); // Provocamos la finalización del quantum de tiempo retardo (); } printf("\n"); V(critica); } exit(); } proceso_padre(critica) int critica; { /* escribe 30 ristras de 80 caracteres '-' */ int i,j; for (i=0;i< 30; i++) { P(critica); for (j=0; j<80; j++) { printf("-"); fflush (stdout); // Provocamos la finalización del quantum de tiempo retardo (); } printf("\n"); V(critica); } wait(0); /* espera a que finalice el hijo */ } /********************************************************************** * * Provocamos la espera durante ESPERA microsegundos * **********************************************************************/ retardo() { struct timeval tiempo; struct timezone tz; unsigned long inicio, ahora; gettimeofday(&tiempo, &tz); ahora = inicio = tiempo.tv_sec * 1000000 + tiempo.tv_usec; // ESPERA microsegs while (ahora < inicio + ESPERA) { gettimeofday(&tiempo, &tz); ahora = tiempo.tv_sec * 1000000 + tiempo.tv_usec; } } /*********************************************************************** * * Rutinas de manejo de semáforos * ***********************************************************************/ inicia(valor) int valor; { int semval; int id; union semun { int val; struct semid_ds *buf; ushort *array; } arg; if ((id=semget(IPC_PRIVATE, 1, (IPC_CREAT|0666))) == -1) { perror("Error al crear el semáforo."); return(-1); } arg.val = valor; if (semctl(id, 0, SETVAL, arg) == -1) { perror("Error al inicializar el semáforo."); return (-1); /*error en inicializacion*/ } return(id); } /*Rutina P */ P(semaforo) int semaforo; { if ( semcall(semaforo, -1) == -1 ) perror("Error en operación P."); } /*Rutina V */ V(semaforo) int semaforo; { if ( semcall(semaforo, 1) == -1 ) perror("Error en operación V."); } semcall(semaforo, operacion) int semaforo, operacion; { struct sembuf sb; sb.sem_num = 0; sb.sem_op = operacion; sb.sem_flg = 0; return ( semop(semaforo, &sb, 1) ); /*devuelve -1 si error */ } borra_s(semaforo) int semaforo; { if ( semctl(semaforo, 0, IPC_RMID, 0) == -1) { perror("Error al eliminar el semáforo."); return(-1); } }