Para a execução, deve-se lançar inicialmente rdv1 (para que a inicialização dos mecanismos IPC seja realizada) e depois rdv2 no mínimo três vezes em background. Após a execução dos programas rdv2, o programa rdv3 pode ser então lançado para destruir os mecanismos IPC implementados pela aplicação.
/* arquivo rdv1.c */ /*-------------------------------------------------------- Rendez-vous de n processos -------------------------- mutex = 1 ; srdv = 0; n = 0 ; N numero de processos a esperar P(mutex, 1) ; n := n + 1 ; if (n < N) then begin V(mutex, 1); P(srdv,, 1); end else begin V(mutex, 1); V(srdv, N); end; ----------------------------------------------------------*/ /* INICIALIZACAO * codigo do processo criador da memoria compartilhada e * dos semaforos */ #include <sys/errno.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/sem.h> #include <stdio.h> #define SHMKEY 75 /* chave para a memoria compartilhada */ #define SEMKEY 76 /* chave para os semaforos */ #define NBSEM 2 /* no. de semaforos (mutex e srdv) */ #define RW 0600 /* permissao de leitura e escrita */ #define K 1024 /* tamanho do segmento de memoria */ int *pmem; int shmid, semid; int main() { short initarray[NBSEM-1], outarray[NBSEM-1]; /* criacao da memoria compartilhada */ if ((shmid = shmget(SHMKEY,K,RW|IPC_CREAT))==-1){ perror("Erro na criacao do segmento de memoria") ; exit(1) ; } pmem = (int *) shmat(shmid, 0, 0); pmem[0] = 0; /* no. de processos que chegaram (0 no inicio) */ pmem[1] = 3; /* no. de processos esperados no ponto de encontro */ /* criacao dos semaforos */ if ((semid = semget(SEMKEY, NBSEM,RW|IPC_CREAT)) == -1){ perror("Erro na criacao de semaforos") ; exit(1) ; } /* inicializacao dos semaforos */ initarray[0] = 1; /* mutex = 1 */ initarray[1] = 0; /* srdv = 0 */ if (semctl(semid, NBSEM-1, SETALL, initarray) == -1){ perror ("inicializacao dos semaforos incorreta") ; exit(1) ; } /* leitura dos parametros dos semaforos */ if (semctl(semid, NBSEM-1, GETALL, outarray) == -1){ perror("leitura dos semaforos incorreta") ; exit(1); }; printf("\n================INICIALIZACAO================\n") ; printf(" numero de processos esperados : %d\n",pmem[1]) ; printf(" numero de processos que chegaram : %d\n",pmem[0]) ; printf(" Para criar um novo processo, digite : rdv2 &\n"); printf("=============================================\n") ; exit(0); }
/* arquivo rdv2.c */ /* codigo executaod pelos processos antes de chegar ao * ponto de encontro (rendez-vous) */ #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/sem.h> #include <sys/errno.h> #include <stdio.h> #define SHMKEY 75 /* chave para a memoria compartilhada */ #define SEMKEY 76 /* chave para os semaforos */ #define K 1024 /* tamanho do segmento de memoria */ int *pmem; int shmid, semid; struct sembuf pmutex[1], vmutex[1], psrdv[1], vsrdv[1] ; int main() { /* recuperacao do shmid */ if ((shmid = shmget(SHMKEY, K, 0)) == -1){ perror("Erro no shmget") ; exit(1) ; } /* recuperacao do semid */ if ((semid = semget(SEMKEY, 2, 0)) == -1){ perror ("Erro no semget") ; exit(1) ; } /* acoplamento ao segmento */ if ((pmem = shmat(shmid, 0, 0)) == (int *)-1){ perror("attachement non effectue") ; exit(1) ; } /* demanda de recurso (P(mutex)) */ pmutex[0].sem_op = -1; pmutex[0].sem_flg = SEM_UNDO; pmutex[0].sem_num = 0; if (semop(semid, pmutex, 1) == -1){ perror("P(mutex) nao efetuado") ; exit(1) ; } /* numero de processos que chegaram */ pmem[0] += 1; /* n = n + 1 */ printf("\nNo. de processos que chegaram = %d de %d\n", pmem[0], pmem[1]); if ( pmem[0] < pmem[1] ){ /* liberacao do recurso (V(mutex)) */ vmutex[0].sem_op = 1; vmutex[0].sem_flg = SEM_UNDO; vmutex[0].sem_num = 0; if (semop(semid, vmutex, 1) == -1){ perror("V(mutex) nao efetuado") ; exit(1) ; } printf("Processo %d: vou me bloquear em espera \n",getpid()); /* demanda de recurso P(srdv) */ psrdv[0].sem_op = -1; psrdv[0].sem_flg = SEM_UNDO; psrdv[0].sem_num = 1; if (semop(semid, psrdv, 1) == -1){ perror("P(srdv) nao efetuado") ; exit(1) ; } } else { printf("Processo %d: Vou liberar todos os processos bloqueados\n", getpid()); /* liberacao de recurso (V(mutex)) */ vmutex[0].sem_op = 1; vmutex[0].sem_flg = SEM_UNDO; vmutex[0].sem_num = 0; if (semop(semid, vmutex, 1) == -1){ perror("liberacao final de mutex nao efetuada") ; exit(1) ; } /* liberacao de 3 recursos */ vsrdv[0].sem_op = pmem[1]; vsrdv[0].sem_flg = SEM_UNDO; vsrdv[0].sem_num = 1; if (semop(semid, vsrdv, 1) == -1){ perror("liberacao final de srdv nao efetuada") ; exit(1) ; } } printf("Processo %d: acabo de passar o ponto de rendez-vous\n", getpid()); exit(0); }
/* arquivo rdv3.c */ /* remocao dos recursos criados por rdv1*/ #include <sys/errno.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/sem.h> #include <stdio.h> #define SHMKEY 75 /* chave para a memoria compartilhada */ #define SEMKEY 76 /* chave para os semaforos */ #define NBSEM 2 /* no. de semaforos (mutex e srdv) */ #define RW 0600 /* permissao de leitura e escrita */ #define K 1024 /* tamanho do segmento de memoria */ int *pmem; int shmid, semid; struct sembuf pmutex[1], vmutex[1], psrdv[1], vsrdv[1] ; int main() { /* recuperacao do shmid */ if ((shmid = shmget(SHMKEY, K, 0)) == -1){ perror("Erro no shmget") ; exit(1) ; } /* recuperacao do semid */ if ((semid = semget(SEMKEY, 2, 0)) == -1){ perror ("Erro no semget") ; exit(1) ; } /* acoplamento ao segmento */ if ((pmem = shmat(shmid, 0, 0)) == (int *)-1){ perror("attachement non effectue") ; exit(1) ; } /* demanda de recurso (P(mutex)) */ pmutex[0].sem_op = -1; pmutex[0].sem_flg = SEM_UNDO; pmutex[0].sem_num = 0; if (semop(semid, pmutex, 1) == -1){ perror("P(mutex) nao efetuado") ; exit(1) ; } if ( pmem[0] > pmem[1] ){ printf("\n================FINALIZACAO================\n") ; printf(" numero de processos esperados : %d\n",pmem[1]) ; printf(" numero de processos que chegaram : %d\n",pmem[0]) ; printf(" Os recursos serao destruidos nesse instante\n"); printf("=============================================\n") ; /* destruicao do semaforo */ if (semctl(semid,0,IPC_RMID,0)==-1){ perror("Impossivel de destruir o semaforo") ; exit(1) ; } /* destruicao do segmento de memoria compartilhada */ if (shmctl(shmid,IPC_RMID,0)==-1){ perror("Impossivel de destruir o segmento de memoria") ; exit(1) ; } } else { /* liberacao do recurso (V(mutex)) */ vmutex[0].sem_op = 1; vmutex[0].sem_flg = SEM_UNDO; vmutex[0].sem_num = 0; if (semop(semid, vmutex, 1) == -1){ perror("V(mutex) nao efetuado") ; exit(1) ; } printf("Processo %d: ainda nao posso destruir os recursos\n", getpid()); printf("Processo %d: faltam ainda %d processos de %d\n", getpid(),(pmem[1]-pmem[0]), pmem[1]); } exit(0); }
Resultado da execução:
margarida:~/> rdv1 ================INICIALIZACAO============== numero de processos esperados : 3 numero de processos que chegaram : 0 Para criar um novo processo, digite : rdv2 & ============================================= margarida:~/> rdv2 & [6] 949 margarida:~/> No. de processos que chegaram = 1 de 3 Processo 949: vou me bloquear em espera margarida:~/> rdv3 Processo 951: ainda nao posso destruir os recursos Processo 951: faltam ainda 2 processos de 3 margarida:~/graduacao/STR/Apostila/Chap8> rdv2 & [7] 952 margarida:~/> No. de processos que chegaram = 2 de 3 Processo 952: vou me bloquear em espera margarida:~> rdv2 & [8] 953 No. de processos que chegaram = 3 de 3 Processo 953: Vou liberar todos os processos bloqueados Processo 949: acabo de passar o ponto de rendez-vous Processo 952: acabo de passar o ponto de rendez-vous Processo 953: acabo de passar o ponto de rendez-vous [8] Done rdv2 [7] Done rdv2 [6] Done rdv2 margarida:~/> rdv3 ================FINALIZACAO================ numero de processos esperados : 3 numero de processos que chegaram : 3 Os recursos serao destruidos nesse instante =============================================