Inter-process communication (2)-message queue and Process Communication Message Queue

Source: Internet
Author: User

Inter-process communication (2)-message queue and Process Communication Message Queue

I will use several blogs to summarize several methods of communication between processes in Linux. I will write the summary at the beginning in each blog of this series.

Communication between processes

  • MPs queue
  • Message Queue
  • Signal
  • Semaphores
  • Shared storage Zone
  • Socket)

This time, I mainly write about message queues. the pipelines and message queues mentioned earlier are essentially different. pipelines are a file, A message queue is a data structure (similar to a linked list ). This shows that pipeline files are stored on disks and shutdown will also exist (especially the named pipeline is more obvious. If you don't delete it, he will stay there ), the message queue exists in the memory in the kernel. Obviously, shutdown is gone.

The more important thing is that the memory is faster than the disk I/O, so why is it so slow. In addition, message queues can directly communicate with unrelated processes. However, the structure is more complex than the pipeline, and many struct are used. There are many contents. First, let's look at the main differences with pipelines for more intuitive comparison.

  • The anonymous pipeline follows the process, and the message queue follows the kernel. That is to say, after the process ends, the anonymous pipeline will die, but the message queue will still exist (unless the call function is destroyed)
  • MPs queues are files and stored on disks. The access speed is slow. Message Queues are data structures and stored in memory. The access speed is fast.
  • Pipelines are data stream access, while message queues are data block-based access.

Start from scratch:

 

  • How to create a message queue

A system call in the C-library function can create a message queue, that is, msgget. Other functions related to this function will also be provided.

  • Function prototype: int msgget (key_t key, int msgflg)
  • Header file: # include <sys/types. h> # include <sys/ipc. h> # include <sys/msg. h>
  • Parameter Parsing
    • The first parameter is a key that uniquely identifies the data structure. You can give IPC_PRIVATE a key that the kernel automatically gives, or you can call the ftok function to bind
    • The second parameter is the parameter used to create a message queue, including IPC_CREAT and IPC_EXCL.
      • Use IPC_CREAT independently. If the Message Queue already exists (that is, the key_t object has been taken to the created Queue), open the queue and return it. If it does not exist, create a return message.
      • It does not make sense to use IPC_EXCL alone
      • The two parameters are used together (IPC_CREAT | IPC_EXCL). If this queue exists, an error is returned. If this queue does not exist, a new queue will be obtained.
  • Return value. A unique int that indicates the message queue is returned successfully.-1 is returned if the message queue fails to be returned.

 

  • Function prototype: key_t ftok (const char * pathname, int proj_id)
  • Header file: # include <sys/types. h> # include <sys/ipc. h>
  • Parameter Parsing
    • There is nothing to parse. The first parameter is to set a path (directory)
    • The second is to give an int value without any special requirements. ftok essentially binds the proj_id and pathname together.

There are so many related functions that we can happily create a new message queue here. How can we see the created message queue? How to destroy him?

Use the command to checkYou can view the status of the message queue by using ipcs-q.Here, I created a message queue and destroyed it below

UseIpcrm-q msqid can destroy a message queue. I have destroyed the created message queue.

How can I destroy a Message Queue through the C function? Use the msgctl Function

  • Function prototype: int msgctl (int msgid, int cmd, struct msgid_ds * buf)
  • Header file: # include <sys/types. h> # include <sys/ipc. h> # include <sys/msg. h>
  • Parameter Parsing
    • The first parameter is the int variable that identifies msg.
    • There are many second parameters. Here we will introduce two. Let's talk about the primary destruction, IPC_RMID. After this is set, the third parameter does not need to be set to 0.
    • When the second parameter is set to IPC_SET, it indicates the initialization of the Message Queue. In this case, the third parameter is useful, but I have not used it here for a detailed explanation of the phone bill.

Here,One disadvantage of message queue is that IPC_SET initializes message queues, which means that the creation and initialization of message queues are separated. This design is not very good because of thread security issues, when a thread has created a message queue and has not been initialized, it will be embarrassing for another thread to directly start accessing the queue.

 1 struct msginfo { 2                       int msgpool; /* Size in kibibytes of buffer pool 3                                       used to hold message data; 4                                       unused within kernel */ 5                       int msgmap;  /* Maximum number of entries in message 6                                       map; unused within kernel */ 7                       int msgmax;  /* Maximum number of bytes that can be 8                                       written in a single message */ 9                       int msgmnb;  /* Maximum number of bytes that can be10                                       written to queue; used to initialize11                                       msg_qbytes during queue creation12                                       (msgget(2)) */13                       int msgmni;  /* Maximum number of message queues */14                       int msgssz;  /* Message segment size;15                                       unused within kernel */16                       int msgtql;  /* Maximum number of messages on all queues17                                       in system; unused within kernel */18                       unsigned short int msgseg;19                                    /* Maximum number of segments;20                                       unused within kernel */21                   };

 

  • Use Message Queue

Message Queue is nothing more than message writing and reading. It involves two functions and a struct.

Sending functions first

  • Function prototype: int msgsnd (int msgid, const void * msgp, size_t msgsz, int msgflg)
  • Header file: # include <sys/types. h> # include <sys/ipc. h> # include <sys/msg. h>
  • Parameter Parsing
    • The first one is the message queue number.
    • The second is a pointer to a struct, which is called msgbuf in the kernel (which should be yes... If not, write a program by yourself.) If necessary, this is the data block for data transmission. If it is not, it cannot be set to 0.
    • The third is the length of the message to be transmitted (generally, the length of your data is long, not the total size of the msgbuf object)
    • The fourth is the transmission mode (no blocking or something) parameter. My program is not used, so I set it to 0.

The struct must be put out before the column accepts the function, otherwise the following will be forced

1 struct msgbuf {2                long mtype;       /* message type, must be > 0 */3                char mtext[1];    /* message data */4            };

SlaveMtypeThis is because the queue is used by many processes (or threads,For example, if four processes share a message queue and communicate with each other, it is necessary to identify which two processes are in a group and which data belongs to your group.The mtype is used to identify,Must be greater than 0When I first set it to 0, I always reported a parameter error. I checked the document and found myself stupid...

Mtext stores the data you want to transmit.How is the size only 1? Of course, it cannot only be 1. The msgbuf I write myself has a length of 1024... So you can write it by yourself.

The function is accepted.

  • Function prototype: ssize_t msgrcv (int msgid, const void * msgp, size_t msgsz,Long msgtyp, Int msgflg)
  • The header file is the same as the msgsnd function.
  • Parameter Parsing
    • Only the marked red part is used, and the others are the same as msgsnd.
    • Msgtyp is used to indicate that when I (the current process) Get data, I only take (mtype in the msgbuf object) the same data block as the msgtyp I passed in (msgbuf object)
  • The length of a successful response.-1 is returned if the request fails.

 

Now, the basic operations have been completed,Show me the code

My program is divided into comm. h (Public header file) comm. c (encapsulate basic functions) server. c (recommended server side) client. c (simple client) a total of 4 files

Complete simple communication between the server and client (back-to-contract chat (mistake ))

Comm. h

 1 #include <stdio.h> 2 #include <unistd.h> 3 #include <sys/msg.h> 4 #include <sys/types.h> 5 #include <sys/ipc.h> 6 #include <string.h> 7 #include <stdlib.h> 8 #include <errno.h> 9 #include <memory.h>10 11 12 #define _PATH_NAME_ "/tmp"13 #define _PROJ_ID_ 0x66614 #define _SIZE_ 102415 16 static int comm_create_msg_set(int flags);17 int create_msg_set();18 int get_msg_set();19 void destory_msg_set(int msg_id);20 void send_msg(int msg_id,long msgtype,char * buf);21 void receive_msg(int msg_id,long msgtype,char *buf);22 23 24 25 struct msgbuf26 {27   long mtype;28   char mtext[_SIZE_];29 };

Comm. c

 1 #include "comm.h" 2 static int comm_create_msg_set(int flags) 3 { 4   key_t _key=ftok(_PATH_NAME_,_PROJ_ID_); 5   if(_key<0) 6   { 7     printf("%d:%s",errno,strerror(errno)); 8   } 9   int msg_id=msgget(_key,flags);10   if(msg_id<0)11   {12     printf("%d:%s",errno,strerror(errno));13   }14   return msg_id;15 }16 17 18 int get_msg_set()19 {20   key_t _key=ftok(_PATH_NAME_,_PROJ_ID_);21   int flags=IPC_CREAT;22   return comm_create_msg_set(flags);23 }24 25 26 int create_msg_set()27 {28   key_t _key=ftok(_PATH_NAME_,_PROJ_ID_);29   int flags=IPC_CREAT | IPC_EXCL;30   return comm_create_msg_set(flags);31 }32 33 34 void send_msg(int msg_id,long msgtype,char *buf)35 {36   memset(buf,'\0',strlen(buf)+1);37   ssize_t _size=read(0,buf,_SIZE_);38   if(_size>0)39   {40     buf[_size-1]='\0';41   }42 43   struct msgbuf _mbuf;44   memset(&_mbuf,'\0',sizeof(struct msgbuf));45   _mbuf.mtype=msgtype;46   strcpy(_mbuf.mtext,buf);47   if(msgsnd(msg_id,&_mbuf,_size,0)<0)48   {49     printf("send error,%d:%s",errno,strerror(errno));50   }51 }52 53 void receive_msg(int msg_id , long msgtype ,char *buf)54 {55   struct msgbuf _mbuf;56   memset(&_mbuf,'\0',sizeof(struct msgbuf));57   _mbuf.mtype=0;58   if(msgrcv(msg_id,&_mbuf,_SIZE_,msgtype,0)<0)59   {60     printf("recv error %d:%s",errno,strerror(errno));61   }62   strcpy(buf,_mbuf.mtext);63 }64 65 void destory_msg_set(int msg_id)66 {67   if(msgctl(msg_id,IPC_RMID,0)<0)68   {69     printf("%d:%s",errno,strerror(errno));70   }71 }

Server. c

 1 #include "comm.h" 2 long c_type=1; 3 long s_type=22; 4 int main() 5 { 6   int msg_id=create_msg_set(); 7   char buf[_SIZE_]; 8  9   while(1)10   {11     memset(buf,'\0',sizeof(buf));12     receive_msg(msg_id,c_type,buf);13     if(strcasecmp(buf,"quit")==0)14     {15       break;16     }17     printf("client # %s\n",buf);18     printf("clent say done ! Please Input:");19     fflush(stdout);20     memset(buf,'\0',sizeof(buf));21     send_msg(msg_id,c_type,buf);22   }23   destory_msg_set(msg_id);24   return 0;25 }

Client. c

 1 #include "comm.h" 2  3  4 long c_type=1; 5 long s_type=2; 6  7 int main() 8 { 9   int msg_id = get_msg_set();10 11   char buf[_SIZE_];12 13   while(1)14   {15     memset(buf,'\0',sizeof(buf));16     send_msg(msg_id,c_type,buf);17     if(strcasecmp(buf,"quit")==0)18     {19       break;20     }21     memset(buf,'\0',sizeof(buf));22     receive_msg(msg_id,c_type,buf);23     printf("server # %s\n",buf);24     printf("server say done ! Please Input:");25     fflush(stdout);26   }27 28   return 0;29 }

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.