next up previous
Next: Exemplos usando IPC Up: As Filas de Mensagens Previous: Função msgsnd()

Função msgrcv()

  # include <sys/types.h>
  # include <sys/ipc.h>
  # include <sys/msg.h>

  int msgrcv ( int msqid, struct msgbuf *msgp, int msgsz,
               long msgtyp, int msgflg )

Valor de retorno: número de bytes da mensagem extraída da fila, ou -1 em caso de erro.

Esta função retira uma mensagem da fila. Ela recebe cinco parâmetros: o identificador da fila msqid; um ponteiro msgp para a estrutura de tipo msgbuf que contém a mensagem; um inteiro msg_sz indicando o tamanho máximo da mensgem a ser recebida; um inteiro longo msgtyp indicando o qual a mensagem a ser recebida e; um flag msgflg controlando o modo de execução da recepção da mensagem.

A função vai armazenar a mensagem lida numa estrutura apontada por msgp, a qual contém os seguintes elementos ( idênticos aos usados para o envio da mensagem):

struct msgbuf
  {
    long int mtype;     /* type of received message */
    char mtext[1];      /* text of the message */
  };

O tamanho do campo mtext é fixado segundo as necessidades do programa (ver msgsnd() para maiores detalhes).

O parâmetro msgtyp indica qual a mensagem deve ser recebida:

Por exemplo, considerando três mensagens tendo por tipos 100, 200 e 300, a tabela a seguir indica o tipo de mensagem a ser retornada pelos diferentes valores de msgtyp:


msgtyp tipo de mensagem retornada
0 100
100 100
200 200
300 300
­100 100
­200 100
­300 100

Em relação ao parâmetro msgflg:

Exemplo:

Exemplo de utilização da função msgrcv():

                /* arquivo test_msgrcv.c */
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>

#define KEY 123
#define MSG_SIZE_TEXT 256
 
/* estrutura msg associada as mensagens */
struct msgtext {
     long mtype ;
     char mtext[MSG_SIZE_TEXT] ;
} msg ;         

int main()
{
int lg ;            /* tamanho da mensagem recebida */
long type = 1 ;     /* tipo de mensagem buscado */
int size_msg = 22 ; /* tamanho maximo do texto a ser recuperado */
int msqid ;         /* identificador da fila */
char *path = "nome_de_arquivo_existente" ;

   /* recuperacao do identificador da fila de mensagens */
   if (( msqid = msgget(ftok(path,(key_t)KEY),0)) == -1 ) {
          perror ("Erro msgget()") ;
          exit(1) ;
   }
   printf("A chave %#x esta associada a fila %d\n",
              ftok(path,(key_t)KEY), msqid);
      /* o programa vai ler na fila enquanto existirem mensagens
    * se as mensagens sao maiores que o tamanho maximo size_msg,
    * elas serao truncadas
    * quando a fila estiver vazia, o processo nao se bloqueia */
   while((lg=msgrcv(msqid,&msg,size_msg,type,IPC_NOWAIT|MSG_NOERROR)) != -1)
   { 
       printf("texto da mensagem (tamanho %d) recebido: %s\n",
               lg,msg.mtext) ;
   }
   perror("nao ha mais mensagens") ;
   exit(-1) ;
}

Resultado da execução:

euler:~/> test_msgrcv
A chave 0x7b045862 esta associada a fila 1152
texto da mensagem (tamanho 22) recebido: mensagem no 1 de tipo 
texto da mensagem (tamanho 22) recebido: mensagem no 2 de tipo 

...

texto da mensagem (tamanho 22) recebido: mensagem no 29 de tipo
texto da mensagem (tamanho 22) recebido: mensagem no 30 de tipo
nao ha mais mensagens: No message of desired type

O programa lê na fila de mensagens enquanto mensagens do tipo desejado existirem na fila. Quando a fila estiver vazia, não haverá bloqueio de processos em leitura devido ao flag IPC_NOWAIT. Por outro lado, deve-se observar que as mensagens são truncadas (flag MSG_NOERROR ao tamanho especificado para a recepção da mensagem. Além disso, ;g será igual ao tamanho da mensagem size_msg neste caso específico, uma vez que a mensagem é truncada.

Mais uma vez, pode-se constatar que a leitura (isto é a retirada) das mensagens da fila foi realmente realizada através da execução de test_msgctl.c:

euler:~/> test_msgctl
A chave 0x7b045862 esta associada a fila 1152
id da fila de mensagens      : 1152
id do proprietario           : 1145
id do grupo do proprietario  : 1000
id do criador                : 1145
id do grupo do criador       : 1000
direitos de acesso           : 384
nb atual de bytes na fila    : 0
nb de mensagens na fila      : 0
nb maximal de bytes na fila  : 16384
pid do ultimo escritor       : 2192
pid do ultimo leitor         : 2194
data da ultima escrita       : Tue Oct 17 06:53:54 2000

data da ultima leitura       : Tue Oct 17 06:57:17 2000

data da ultima modificacao   : Tue Oct 17 06:43:09 2000

Note que o número de mensagens na fila agora vale 0 e que a data da última escrita na fila é idêntica àquela obtida na execução precedente de test_msgctl.


next up previous
Next: Exemplos usando IPC Up: As Filas de Mensagens Previous: Função msgsnd()
Celso Alberto Saibel Santos 2000-11-14