El siguinte código crea cuatro procesos hijos. Cada hijo incrementará una variable compartida en 5 unidades. Para garantizar la exclusión mútua sobre la variable compartida se utiliza un grupo de un semáforo que funciona como semáforo binario.
Hay que cabiar todas las " de los includes por mayor y menor excepto el include de sv.h.
/**
Implementa un semáforo binario
utilizando directamente las funciones del sistema
**/
#include "sv.h"
#include "stdio.h"
#include "wait.h>
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "sys/ipc.h"
#include "sys/sem.h"
// Incrementa en 5 la variable compartida
#define INC 5
void inc(int);
// Esta unión hay que declararla
union semun {
int val;
struct semid_ds *buf;
ushort *array;
};
int main() {
int c;
int hijos = 4;
pid_t pid;
int semaforo;
union semun arg;
int r;
// { semaforo, valor, banderas }
struct sembuf arriba = {0, 1, 0};
struct sembuf abajo = {0, -1, 0};
sv_init();
printf("Valor de inicio: %i\n", sv_val());
// Crear e inicializar un semaforo binario
// para garantizar la exclusion mutua.
semaforo = semget(42, 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
if (semaforo == -1) {
perror ("Error en la creación del semáforo - ");
return -1;
}
arg.val = 1;
r = semctl(semaforo, 0, SETVAL, arg);
if (r == -1) {
perror ("Error inicializando semáforo - ");
// Hay que eliminarlo.
return -1;
}
for (c = 0; c < hijos; c++) {
pid = fork();
if (pid == -1) {
perror("Error en fork - ");
exit(-1);
}
if (pid == 0) {
// Decrementar semaforo
r = semop(semaforo, &abajo, 1);
if (r == -1) {
perror("Error decrementando semáforo - ");
// Eliminar el semáforo
return -1;
}
inc(c);
// Incrementar semaforo
r = semop(semaforo, &arriba, 1);
if (r == -1) {
perror("Error incrementando semáforo - ");
// Es necesario eliminarlo
return -1;
}
exit(0);
}
}
while ( wait(NULL)!=-1 );
printf("-------------------------------\n");
printf("Valor esperado: %i\n", hijos * INC);
printf("Valor real: %i", sv_val());
// Borrar semaforo
r = semctl(semaforo, 0, IPC_RMID);
if (r == -1)
{
perror("Error elminando semáforo - ");
return -1;
}
sv_finish();
printf("\n");
}
//----------------------------
void inc(int id) {
int c;
int tmp;
for(c=0; c < INC; c++) {
tmp = sv_get();
if ( (id == 0) && (c < 2)) sleep(1);
tmp++;
sv_set(tmp);
}
}
No comments:
Post a Comment