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 =============================================