14.2.05

Libería para implementar una variable compartida

A continuación se incluye el código de una librería que permite crear y manipular una variable compartida, esto es, una variable común para todos los procesos que utilicen esta librería. Así, los cambios que haga un proceso sobre esta variable, serán visibles para los demás procesos.

Esta librería es un buen ejemplo de como utilizar el mecanismo IPC de memoria compartida.

Esta librería se utilizará en ejemplos posteriores con semáforos.

sv.h


#ifndef _SV_
#define _SV_

/**
Gestiona una variable entera mediante memoria compartida.
La variable es común a todos los procesos creados
después de llamar a sv_init();
**/


/**
Reserva la memoria compartida e inicializa la variable
a 0.
-1 si error.
**/
int sv_init();

/**
Libera la memoria compartida.
-1 si error.
**/
int sv_finish();

/**
Devuelve el valor de la variable común
sv_get es un alias para sv_vsl
**/
int sv_val();
int sv_get();

/**
Incrementa la variable entera con el valor
indicado como parámetro y devuelve su nuevo valor.
**/
int sv_inc(int);

/**
Asigna un valor a la variable común
Devuelve el valor asignado.
**/
int sv_set(int);

#endif





sv.c


#include "stdio.h"
#include "sys/ipc.h"
#include "sys/shm.h"
#include "sys/stat.h"
#include "sys/types.h"

int s_id;
int *sv = NULL;

//---------------------------------
int sv_init() {
int tam = sizeof(int);
s_id = shmget(IPC_PRIVATE, tam, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
if (s_id == -1)
return -1;
sv = (int *)shmat(s_id, NULL, 0);
if (sv == (int *)-1) {
sv = NULL;
return -1;
}
(*sv)=0;
return 1;
}

//--------------------------------
int sv_inc(int val) {
int tmp;
if (sv == NULL)
return -1;
tmp = (*sv);
tmp += val;
(*sv)= tmp;
return (tmp);
}

//--------------------------------
int sv_val() {
if (sv == NULL)
return 0;
return (*sv);
}

//--------------------------------
int sv_get() {
return sv_val();
}

//--------------------------------
int sv_set(int val) {
(*sv) = val;
return val;
}

//--------------------------------
int sv_finish() {
if (s_id == -1)
return -1;
return shmctl(s_id, IPC_RMID, 0);
}

No comments: