next up previous
Next: Exemplo2: Cliente-servidor Up: Exemplos usando IPC Previous: Exemplos usando IPC

Exemplo1: Rendez­vous de três processos

O exemplo dessa seção apresenta a implementação de um mecanimo derendez-vous (ponto de encontro ou sincronização) entre três processos. O primeiro programa (rdv1) cria um conjunto de dois semáforos (um para a exclusão mútua e outro para o ponto de rendez-vous), e um segmento de memória compartilhada permitindo que cada um dos processos saibam na sua chegada, o número de processos que já estão no ponto de encontro. O segundo programa (rdv2) simula os processos que devem chegar a esse ponto. O terceiro programa (rdv3) serve para destruir os recursos criados por rdv1. Entretanto, se ele for lançado antes da chegada de no mínimo três ao ponto de rendez-vous, os recursos permanecerão intactos.

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


next up previous
Next: Exemplo2: Cliente-servidor Up: Exemplos usando IPC Previous: Exemplos usando IPC
Celso Alberto Saibel Santos 2000-11-14