martes, 12 de octubre de 2010

Semaforos del Sistema en C/C++ sobre Linux


Crear semaforos en Linux para sincronizar procesos

#include <sys/ipc.h>
#include <sys/sem.h>

void main()
{

    key_t llave;
    int id_semaforo;

    //algun archivo para crear la llave, todos los procesos
    //que desean obtener la misma llave deben pasar los mismos
    //parametros, con la misma llave tambien se adquiere el mismo 
    //conjunto de semaforos
    llave = ftok("/bin/bash", 'X');

    //crear 10 semaforos con persimos 0666 (rw-rw-rw-)
    id_semaforo = semget( llave, 10, 0666 | IPC_CREAT);
}

al crear los semaforos en un proceso, es posible adquirir el mismo conjunto de semaforos desde otro proceso con una llamada a semget

#include <sys/ipc.h>
#include <sys/sem.h>

void main()
{

    key_t llave;
    int id_semaforo;

    //la misma llave para obtener acceso al conjunto de semaforos creado
    llave = ftok("/bin/bash", 'X');

    id_semaforo = semget( llave, 10, 0);
}

configurar el valor inicial de un semaforo y acceder al valor actual del semaforo

#include <sys/ipc.h>
#include <sys/sem.h>

union semun {
    int val;              
    struct semid_ds *buf; 
    ushort *array;        
};


void main()
{

    key_t llave;
    int id_semaforo;

    llave = ftok("/bin/bash", 'X');

    id_semaforo = semget( llave, 10, 0666 | IPC_CREAT );

    //estructura que parametriza la funcion semctl
    semun arg;    

    arg.val = 1; //valor inicial para el semaforo

    //configurar el semaforo con indice 0 del arreglo de 10 a 1 
    semctl( id_semaforo, 0, SETVAL, arg );

    //configurar el semaforo con indice 1 del arreglo de 10 a 1
    semctl( id_semaforo, 1, SETVAL, arg );
 
    //obtener el valor actual del semaforo con indice 1
    int valorActual = semctl( id_semaforo, 1, GETVAL );

}

operaciones Up() y Down()

#include <sys/ipc.h>
#include <sys/sem.h>

void main()
{

    key_t llave;
    int id_semaforo;

    llave = ftok("/bin/bash", 'X');

    id_semaforo = semget( llave, 10, 0666 | IPC_CREAT );

    sembuf accion; 

    // UP 
    accion.sem_num = 0; //indice del semaforo
    accion.sem_op = 1; //operacion enteros positivos se agregan al semaforo
    accion.sem_flg = 0; 

    //identificador, arreglo de sembuf y cantidad de elementos de dicho 
    //arreglo, seria posible ejecutar varias acciones al mismo tiempo
    semop ( id_semaforo, &accion, 1 );

    //DOWN
    accion.sem_num = 0; //indice del semaforo
    accion.sem_op = -1; //operacion enteros negativos se restan del semaforo
    //si el valor actual del semaforo es menor que el entero negativo 
    //el proceso se duerme hasta que el valor del semaforo es mayor
    accion.sem_flg = 0; 

    semop ( id_semaforo, &accion, 1 );

}

remover los semaforos

#include <sys/ipc.h>
#include <sys/sem.h>

void main()
{

    key_t llave;
    int id_semaforo;

    //algun archivo para crear la llave, todos los procesos
    //que desean obtener la misma llave deben pasar los mismos
    //parametros, con la misma llave tambien se adquiere el mismo 
    //conjunto de semaforos
    llave = ftok("/bin/bash", 'X');

    //crear 10 semaforos con persimos 0666 (rw-rw-rw-)
    id_semaforo = semget( llave, 10, 0666 | IPC_CREAT);

    //remover los semaforos creados
    semctl( id_semaforo, 0, IPC_RMID);

}