O programa dijsktra.h realiza a implementação dos semáforos de Dijkstra a partir dos mecanismos de semáforos IPC disponíveis no sistema. A função sem_create() possibilita criação de um semáforo. As operações P e V são realizadas pelas funções P() e V(). A função sem_delete() possibilita a destruição do semáforo.
/* arquivo dijkstra.h */
/* Implementacao dos semaforos de Dijkstra usando IPC
*
* sem_create(): criacao de um semaforo de Dijkstra
* P() : realizacao da operacao P sobre o semaforo
* V() : realizacao da operacao V sobre o semaforo
* sem_delete() : destruicao do semaforo
*/
/* criacao de um semaforoa associado a */
/* chave key, com valor initial initval */
int sem_create(key_t key, int initval)
{
int semid ;
union semun {
int val ;
struct semid_ds *buf ;
ushort array[1] ;
} arg_ctl ;
semid = semget(ftok("dijkstra.h",key),1,IPC_CREAT|IPC_EXCL|0666) ;
if (semid == -1) {
semid = semget(ftok("dijkstra.h",key),1,0666) ;
if (semid == -1) {
perror("Erro semget()") ;
exit(1) ;
}
}
arg_ctl.val = initval ;
if (semctl(semid,0,SETVAL,arg_ctl) == -1) {
perror("Erro inicializacao semaforo") ;
exit(1) ;
}
return(semid) ;
}
void P(int semid)
{
struct sembuf sempar[1];
sempar[0].sem_num = 0 ;
sempar[0].sem_op = -1 ;
sempar[0].sem_flg = SEM_UNDO ;
if (semop(semid, sempar, 1) == -1)
perror("Erro operacao P") ;
}
void V(int semid)
{
struct sembuf sempar[1];
sempar[0].sem_num = 0 ;
sempar[0].sem_op = 1 ;
sempar[0].sem_flg = SEM_UNDO ;
if (semop(semid, sempar, 1) == -1)
perror("Erro operacao V") ;
}
void sem_delete(int semid)
{
if (semctl(semid,0,IPC_RMID,0) == -1)
perror("Erro na destruicao do semaforo");
}
Testando os semáforos de Dijkstra
/* arquivo test_sem_dijkstra.c */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <unistd.h>
#include "dijkstra.h"
#define KEY 456
int main()
{
int sem ;
sem = sem_create(KEY,1) ;
printf("\nCriacao do semaforo do identificador %d\n",sem) ;
// P(sem);
if (fork() == 0) {
printf("\tEu sou o FILHO e fazer P sobre o semaforo\n");
P(sem);
printf("\tEu sou o FILHO e vou dormir 10 segundos...\n") ;
sleep(10) ;
printf("\tEu sou o FILHO e vou fazer V sobre o semaforo\n") ;
V(sem) ;
sleep(1);
}
else {
printf("Eu sou o PAI e vou dormir 2 segundos...\n") ;
sleep(2);
printf("Eu sou o PAI e vou me bloquear fazendo P sobre o semaforo\n");
P(sem) ;
printf("Eu sou o PAI e acabei de me desbloquear\n") ;
sem_delete(sem) ;
printf("Eu sou o PAI e vou acabar o processamento\n\n");
}
exit(0);
}