Chapter 5 - Concurrency: Mutual Exclusion and Synchronization

Comunicação entre Processos: "Pipes" e "Shared Memory"

 

1. Pipes são criados com a chamada de sistema pipe. A chamada retorna dois descritores de arquivos, sendo o primeiro para leitura e o segundo para gravação. Esta chamada, em geral, se processa antes de ocorrer um fork. Se a comunicação for no sentido pai -> filho, o processo pai fecha o primeiro descritor (com a chamada close), e o filho o segundo. A partir daí, o pai executa chamadas write no segundo descritor e o filho read no primeiro. Um segundo pipe pode ser empregado para a comunicação no sentido inverso, atentando-se para o fechamento correto dos descritores que não serão empregados pelo processo. Veja o exemplo abaixo.

 
  /* **************************************** Includes */
  #include 
  #include 
  #include 


  /* ************************************************** Main Program */
  int main( int argc, char* argv[] )
  {
    int fd[2];
    char buff[32];

    if( pipe(fd) == -1 ) {
      perror("pipe");
      exit(0);
    }

    if( fork() != 0 ) {  /* Processo PAI */
      close( fd[0] );
      printf("Processo PAI: ... envia mensagem p/ FILHO => \"Oi FILHO\".\n");
      strcpy( buff, "Oi FILHO!");
      write( fd[1], buff, strlen(buff)+1 );
      close( fd[1] );
      sleep(20);
      wait(NULL);
      exit( 0 );
    }
    else {
      close( fd[1] );
      printf("\tProcess FILHO: ... recebe mensagem do PAI.\n");
      read( fd[0], buff, 32);
      printf("\tMensagem: ... \"%s\".\n", buff);
      close( fd[1] );
      sleep(20);
      exit( 0 );
    }
}
 

2. Mensagens são enviadas com a chamada de sistema msgsnd. A chamada possui quatro parâmetros: o identificador do port para o qual a mensagem deve ser enviada; a estrutura que contém a mensagem; seu tamanho em bytes; e a opção de envio assíncrono (retornando um código de erro caso não exista espaço para o núcleo armazenar a mensagem no port). A opção default é o envio síncrono, onde o processo bloqueia ante a impossibilidade de armazenamento da mensagem no port. Veja o exemplo abaixo.

 
  /*
  ** sh-mmry1.c - escreve um poema em uma area compartilhada na memoria
  */

  /* **************************************** Includes */
  #include 
  #include 
  #include 
  #include 


  /* **************************************** Defines */
  #define KEY 67
  extern char *shmat();


  /* **************************************** Tipos de Dados */
  struct mssg {
    int tipo;
    char content[1024];
  };


  /* ************************************************** Main Program */
  int main( int argc, char* argv[] )
  {
    char *buff, *poema[16];
    int i, sh;

    printf("Programa: \"Escreve POEMA de uma Area Compartilhada\". \n");

    /* Cria Area Compartilhada */
    sh = shmget( KEY, 1024, 0777 | IPC_CREAT );

    /* Associa Area Compartilhada com um Endereco Local */
    buff = shmat( sh, 0, 0 );

    poema[0] = "As armas e os barcos assinalados";
    poema[1] = "Que da ocidental praia Lusitana";
    poema[2] = "Por mares nunca dantes navegados";
    poema[3] = "Passaram ainda alem de Tapobrana";
    poema[4] = "E, em perigos e guerras esforcados";
    poema[5] = "Mais do que prometia a forca humana";
    poema[6] = "Por gente remota edificaram";
    poema[7] = "Novo reino, que tanto sublimaram";
    /* Armazena o texto na Area Compartilhada */

    for( i=0; i<8; i++ )
      strcpy( buff + i*100, poema[i] );

    exit(0);
  }
 
 
  /*
  ** sh-mmry2.c - le um poema de uma area compartilhada em memoria.
  */

  /* **************************************** Includes */
  #include 
  #include 
  #include 
  #include 


  /* **************************************** Defines */
  #define KEY 67
  extern char *shmat();


  /* **************************************** Tipos de Dados */
  struct mssg {
    int tipo;
    char content[1024];
  };


  /* ************************************************** Main Program */
  int main( int argc, char* argv[] )
  {
    char *buff, *poema[16];
    int i, sh;

    printf("Programa: \"Le POEMA de uma Area Compartilhada\". \n");

    /* Cria Area Compartilhada */
    sh = shmget( KEY, 1024, 0777 | IPC_CREAT );

    if( sh < 0 ) {
      printf("Error: Area Compartilhada nao Criada. \n");
      exit(0);
    }

    /* Associa Area Compartilhada a um Endereco Local */
    buff = shmat( sh, 0, 0 );

    /* Acessa Texto da Area Compartilhada */
    for( i=0; i<8; i++ )  poema[i] = (buff + i*100);

    for( i=0; i<8; i++ )  printf("\n%s", poema[i]);
    printf("\n\n");

    exit(0);
  }
 

 


Luís Fernando Faina
Last modified: Fri Jun 4 10:12:31 2004