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); }