Message queue for inter-process communication in Linux (2)

Foreword:

   A message queue is a linked list of messages. A message can be thought of as a record, with a specific format and a specific priority. A process that has write permission to the message queue can add new messages to it according to certain rules; a process that has read permission to the message queue can read messages from the message queue.

function:


1. Create a new message queue or get an existing message queue

原型:int msgget(key_t key, int msgflg);

parameter:

     key: It can be considered as a port number, or it can be generated by the function ftok.

     msgflg: IPC_CREAT value, if there is no such queue, create one and return a new identifier; if it already exists, return the original identifier.

                IPC_EXCL value, if there is no queue, it returns -1; if it already exists, it returns 0.

2. Read/write messages to the queue

prototype:

msgrcv takes the message from the queue: ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

msgsnd puts data into the message queue: int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

parameter:

     msqid: the identification code of the message queue

     msgp: pointer to the message buffer, this location is used to temporarily store the sent and received messages, it is a user-definable general structure, the shape is as follows: 


struct msgstru{
     long mtype; //大于0
     char mtext[512];
};

     msgsz: The size of the message.

     msgtyp: The form of the message read from the message queue. A value of zero means that all messages in the message queue will be read.

  msgflg: Used to indicate the action that the core program should take when there is no data in the queue. If msgflg and constant IPC_NOWAIT are used together, if the message queue is full when msgsnd() is executed, msgsnd() will not block, but will return -1 immediately. If msgrcv() is executed, the message queue will be empty. , return -1 immediately without waiting, and set the error code to ENOMSG. When msgflg is 0, msgsnd() and msgrcv() adopt the processing mode of blocking and waiting when the queue is full or empty.

3. Set message queue properties

原型:int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );

Parameter: The msgctl system call executes the cmd operation on the message queue identified by msgqid. The system defines three cmd operations: IPC_STAT , IPC_SET , IPC_RMID
      IPC_STAT : This command is used to obtain the msqid_ds data structure corresponding to the message queue and save it to the specified buf address space.
      IPC_SET : This command is used to set the properties of the message queue. The properties to be set are stored in buf.     

      IPC_RMID : Remove the message queue identified by msqid from the kernel.

Example:

Message sender: send.c

 1 /*send.c*/  
 2 #include <stdio.h>   
 3 #include <sys/types.h>   
 4 #include <sys/ipc.h>   
 5 #include <sys/msg.h>   
 6 #include <errno.h>   
 7 
 8 #define MSGKEY 1024   
 9   
10 struct msgstru  
11 {  
12    long msgtype;  
13    char msgtext[2048];   
14 };  
15   
16 main()  
17 {  
18   struct msgstru msgs;  
19   int msg_type;  
 20    char str[ 256 ];  
 21    int ret_value;  
 22    int msqid;  
 23    
24    msqid=msgget(MSGKEY,IPC_EXCL);   /* Check if the message queue exists */   
25    if (msqid < 0 ){  
 26      msqid = msgget (MSGKEY,IPC_CREAT| 0666 ); /* Create message queue */   
27      if (msqid < 0 ){  
 28      printf( " failed to create msq | errno=%d [%s]\n " ,errno,strerror(errno) );  
 29     exit(-1);  
30     }  
31   }   
32    
33   while (1){  
34     printf("input message type(end:0):");  
35     scanf("%d",&msg_type);  
36     if (msg_type == 0)  
37        break;  
38     printf("input message to be sent:");  
39     scanf ("%s",str);  
40     msgs.msgtype = msg_type;  
 41      strcpy(msgs.msgtext, str);  
 42      /* Send message queue */   
43      ret_value = msgsnd(msqid,&msgs, sizeof ( struct msgstru),IPC_NOWAIT);  
 44      if ( ret_value < 0 ) {  
 45         printf( " msgsnd() write msg failed,errno=%d[%s]\n " ,errno,strerror(errno));  
 46         exit(- 1 );  
 47      }  
 48    }  
 49    msgctl(msqid,IPC_RMID, 0 ); // delete the message queue   
50 }  

message receiver receive.c


 1 /*receive.c */  
 2 #include <stdio.h>   
 3 #include <sys/types.h>   
 4 #include <sys/ipc.h>   
 5 #include <sys/msg.h>   
 6 #include <errno.h>   
 7   
 8 #define MSGKEY 1024   
 9   
10 struct msgstru  
11 {  
12    long msgtype;  
13    char msgtext[2048];  
14 };  
15   
16 /*子进程,监听消息队列*/  
17 void childproc(){  
18   struct msgstru msgs;  
 19    int msgid,ret_value;  
 20    char str[ 512 ];  
 21      
22    while ( 1 ){  
 23       msgid = msgget(MSGKEY,IPC_EXCL ); /* Check if the message queue exists */   
24       if (msgid < 0 ) {  
 25          printf( " msq not existed! errno=%d [%s]\n " ,errno,strerror(errno));  
 26          sleep( 2 );  
 27          continue ;  
 28       }  
 29       /*接收消息队列*/  
30      ret_value = msgrcv(msgid,&msgs,sizeof(struct msgstru),0,0);  
31      printf("text=[%s] pid=[%d]\n",msgs.msgtext,getpid());  
32   }  
33   return;  
34 }  
35   
36 void main()  
37 {  
38   int i,cpid;  
39   
40   /* create 5 child process */  
41   for (i=0;i<5;i++){  
42      cpid = fork();  
43      if (cpid < 0)  
44         printf("fork failed\n");  
45      else if (cpid ==0) /*child process*/  
46         childproc();  
47   }  
48 }  
49     

Author: lpshou
Blog: http://www.cnblogs.com/lpshou/
If you live with a lame person you will learn to limp

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324453410&siteId=291194637