Programa executado pelo processo1
/* arquivo processo1.c */ #include <errno.h> #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <unistd.h> #define KEY 123 int semid ; struct sembuf operacao[1] ; char *path = "nome_de_arquivo_existente" ; union { int val ; struct semid_ds *buf ; ushort array[4] ; } arg ; int main() { /* criacao de um conjunto de de 4 semaforos */ if (( semid = semget(ftok(path,(key_t)KEY),4,IPC_CREAT|0600))==-1){ perror("impossivel a criacao do conjunto de semaforos") ; exit(1) ; } printf("\nprocesso1: acabo de criar um conjunto de semaforos:%d\n",semid); /* colocando 1 no terceiro semaforo */ arg.val=1 ; if ((semctl(semid,2,SETVAL,arg))==-1){ perror("Error semctl") ; exit(1); } /* demanda de recurso pelo terceiro semaforo */ printf("processo1: vou demandar um recurso\n") ; operacao[0].sem_num = 2 ; /* operacao sobre o terceiro semaforo */ operacao[0].sem_op = -1 ; /* operacao de decremento */ operacao[0].sem_flg = SEM_UNDO; /* para desfazer as operacoes */ if ( semop(semid,operacao,1) == -1){ perror("semop:operacao de decremento nao realizada") ; exit(1) ; } /* espera para bloquear o segundo processo */ printf("processo1: Esperando 10 sec\n") ; sleep(10) ; /* espera ... */ printf("processo1: Acabei minha espera: liberando o recurso\n"); /* liberacao do recurso */ operacao[0].sem_op = 1 ; /* incremento */ if ( semop(semid,operacao,1) == -1){ perror("semop:operacao de incremento nao realizada") ; exit(1) ; } printf("morte de processo1\n") ; exit(0) ; }
Programa executado pelo processo2
/* arquivo processo2.c */ #include <errno.h> #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <unistd.h> #define KEY 123 int semid ; struct sembuf operacao[1] ; char *path = "nome_de_arquivo_existente" ; int main() { /* recuperacao du semid */ if (( semid = semget(ftok(path,(key_t)KEY),0,0))==-1){ perror("impossivel achar o conjunto de semaforos") ; exit(1) ; } printf("\nprocesso2: trata os semaforos : semid %d\n",semid) ; /* Laco de espera da disponibilidade do semaforo. * O processo nao fara uma espera bloquante usando * o flag IPC_NOWAIT */ operacao[0].sem_num = 2 ; operacao[0].sem_op = -1 ; operacao[0].sem_flg = IPC_NOWAIT + SEM_UNDO ; for (;;){ if ( semop(semid,operacao,1) != -1) break ; printf(" demanda do processo2 : semaforo nao disponivel\n") ; sleep(1) ; } printf(" semaforo alocado ao processo2\n") ; /* liberacao do segmento de semaforo */ if (semctl(semid,0,IPC_RMID,0) == -1){ perror("problema durante a destruicao dos semaforos") ; exit(1) ; } exit(0); }
Resultado da execução
Os dois processos são lançados em background e o resultado
deve ser o seguinte:
euler:~/> processo1 & [2] 967 euler:~/> processo1: acabo de criar um conjunto de semaforos : 768 processo1: vou demandar um recurso processo1: Esperando 10 sec euler:~/> processo2 & [3] 968 euler:~/> processo2: trata os semaforos : semid 768 demanda do processo2 : semaforo nao disponivel demanda do processo2 : semaforo nao disponivel demanda do processo2 : semaforo nao disponivel demanda do processo2 : semaforo nao disponivel demanda do processo2 : semaforo nao disponivel demanda do processo2 : semaforo nao disponivel demanda do processo2 : semaforo nao disponivel demanda do processo2 : semaforo nao disponivel processo1: Acabei minha espera: liberando o recurso morte de processo1 [2] Done processo1 semaforo alocado ao processo2 [3] Done processo2 euler:~/>