Ejemplo Semaforo
#include "stdio.h"
#include "sys/types.h"
#include "sys/ipc.h"
#include "sys/sem.h"
#include "sys/time.h"
#include "unistd.h"
#include "errno.h"
#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);
}
}
En esta parte se puede descargar el programa