interprocess communication (IPC) Message Queuing

Source: Internet
Author: User
Tags message queue posix

The ★ipc method includes pipes, message queues (message_queue), semaphores, Shared Memory (Sharememory), and sockets. Into

Process communication mainly includes pipelines, system IPC (including message queue, signal, and shared storage), socket (socket). This article will describe in detail the phase of Message Queuing


★ Cause:

The so-called message queue, is actually the message (data) during the transmission of the container saved. since there is a way to communicate with the pipeline, why do you have a message queue?

Because according to the characteristics of the pipeline, we know that there is a certain degree of limitations, the first anonymous pipeline and named pipe is the process, in

The end of the pipeline life cycle, and secondly, the pipeline transmits data in the form of unformatted byte stream, which sometimes gives the program development

In addition, the size of the buffer that serves as a conduit for data transmission media is also limited. So another way to use it as an IPC

The Message Queuing approach to interprocess communication has emerged.

★ What is Message Queuing?

a message queue is a linked list of messages. You can think of a message as a record, with a specific format and a specific priority. Write to Message queue

Rights process can add a new message to a message queue, and a process that has read access to the message queue can read the message from the message queue

. Message Queuing is persistent with the kernel. in other words, if the process exits, if you do not voluntarily release the resources, Message Queuing will silently exist. So

more pipeline, the life cycle of Message Queuing is more durable.  Message Queuing provides a way to send a block of data from one process to another.

Each block of data is considered to have a type, and the receiver process receives a data block that can have different type values. We can avoid them by sending messages

Life the synchronization and blocking problems of the name pipeline. Message Queuing differs from a pipeline in that Message Queuing is message-based and the pipeline is byte-stream based, and the message fleet

column the read is not necessarily first-in, first-out. Message Queuing has the same disadvantage as named Pipes, which is that the maximum length of each message is capped

(Msgmax), the total number of bytes per message queue is capped (MSGMNB), and the total number of message queues on the system also has an upper limit

(Msgmni). See:

★ Type of Message queue:

There are currently POSIX message queues and System V message queues, and the System V message queue is currently heavily used. Considering the portability of the program, the newly developed

Applications should use POSIX Message Queuing as much as possible.

The System V Message queue is persistent with the kernel, and the message queue is actually deleted only if the kernel restarts or if a message queue is deleted

(compared to pipelines, the life cycle of a pipeline is with the process). So the data structure (struct Ipc_ids msg_ids) that records Message Queuing in the system is located in

In the kernel, all message queues in the system can find access portals in the structure msg_ids. A message queue is a linked list of messages. Each message team

Column has a queue header, described by struct struct msg_queue. The queue header contains a large amount of information about the message queue, including the message queue key

Value, user ID, group ID, number of messages in Message Queuing, and so on, even the most recent ID of the message queue read and write process. Readers can access this information,

You can also set some of these information.

Now that Message Queuing is one of the IPC (Inter process Communication), let's take a look at the data that the kernel maintains for each inter-process communication object


command: vim/usr/include/linux/ipc.h

Note: You can see that the structure contains a lot of information about the ID, key is similar to the port number, the target gets (get) when the flag;

The UID is the owner of the Id;gid for the group user Id;cuid C is the creator (creator); cgid the same; mode is the pattern, that is, the permission; seq

to a sequential value.

Let's take a look at the structure of the message queue:

command: Vim/usr/include/linux/msg.h

Note: We can see that the content in the red box is the structure of the IPC above. The message queue private data members are private parts, the content corresponding to the comments, it is not

One by one were narrated.

★ Related functions:


Note: The Msgget function contains two parameters key and MSGFLG. The parameter key is similar to the port number or can be generated by the fork function. There are two IPC labels in the parameter MSGFLG

The Ipc_creat and Ipc_exel.

Where the ①IPC_CREAT flag: If the IPC does not exist, create an IPC resource, otherwise open the operation.

②IPC_EXCL: The new shared memory is established only if the shared memory does not exist, or an error occurs. If Ipc_creat,xxxget () is used alone

The function either returns an operator of the shared memory that already exists, or returns an identifier for the newly created shared memory.

③ if the ipc_creat and IPC_EXCL flags are used together, Xxxget () returns a new IPC identifier, if the IPC resource already exists, or

Back-1. The IPC_EXEL flag itself does not make much sense, but it can be used together with the IPC_CREAT flag to guarantee that the resulting object is new, rather than opening an existing

The object.


Note: MSGRCV the message from the queue and msgsnd the data into the message queue;

Function parameters: msqid------The identifier of the message queue; MSGP-------Pointer to the message buffer, which is used to temporarily store messages sent and received, is a

User-definable generic structure with the following morphology: struct msgstru{long mtype;//greater than 0 Char mtext[user designation big? Small];} ; MSGSZ------

The size of the---message; Msgtyp---------the message morphology read from the message queue. A value of zero indicates that all messages in the message queue will be read; msg?g--

------used to indicate the action that the core program should take in cases where the queue has no data. If the msg?g and constant ipc_nowait are pooled, then when the msgsnd () is executed

Is the message queue is full, then msgsnd () will not block, and will immediately return-1, if the execution is MSGRCV (), when the message queue is empty, do not wait for the immediate return

Back-1, and set the error code to enomsg. When Msg?g is 0 o'clock, msgsnd () and MSGRCV () take a blocking wait processing mode when the queue is full or empty.


Note: This function sets the properties of the message queue. Function parameters: The MSGCTL system invokes a CMD operation on the message queue identified by the msgqid, and the system defines 3 cmd operations:

Ipc_stat, Ipc_set, Ipc_rmid?

Ipc_stat: This command is used to get the MSQID_DS data structure corresponding to the message queue and save it to the BUF specified address space.

Ipc_set: This command is used to set the properties of Message Queuing, and the properties to be set are stored in BUF.

Ipc_rmid: Removes the MSQID identity message queue from the kernel.

★ Simulation of communication between client and server with Message Queuing:


#pragma once    #include <stdio.h>  #include <errno.h>  #include <string.h>  #include <sys/types.h>  #include <sys/ipc.h>  #include <sys/msg.h>    #define _PATH_NAME_ "/tmp"  #define _PROJ_ID_ 0x6666  #define _SIZE_    , extern int server_type;  extern int client_type;      struct Msgbuf  {      long mtype;      Char mtext[_size_];  };    int Creat_msg_queue ();  int Get_msg_queue ();  int creat_msg_queue (int msg_id);  int send_msg (int msg_id,int send_type,const char* msg);  int recv_msg (int msg_id,int recv_type,char* msg_out);  int destroy_queue (int msg_id);  


#include "comm.h" int server_type = 1;      int client_type = 2;      static int comm_msg_queue (int flags) {key_t _key = Ftok (_path_name_,_proj_id_);          if (_key < 0) {printf ("%d:%s", Errno,strerror (errno));      return-1;      } int msg_id = Msgget (_key,flags); int msg_id = Msgget (_key,ipc_creat | Ipc_excl |      0666);  return msg_id; } int Creat_msg_queue () {int flags = Ipc_creat | Ipc_excl |      0666;  return Comm_msg_queue (Flags);      } int Get_msg_queue () {int flags = Ipc_creat;  return Comm_msg_queue (Flags); } int destroy_queue (int msg_id) {if (Msgctl (msg_id,ipc_rmid,null)! = 0) {printf ("%d:%s", errno,st          Rerror (errno));      return-1;  } return 0;      } int send_msg (int msg_id,int send_type,const char* msg) {struct MSGBUF _buf;      _buf.mtype = Send_type;        strncpy (_buf.mtext,msg,strlen (msg) +1);      if (Msgsnd (msg_id,&_buf,sizeof (_buf.mtext), 0) < 0){printf ("%d:%s", Errno,strerror (errno));      return-1;  } return 0;      } int recv_msg (int msg_id,int recv_type,char* msg_out) {struct MSGBUF _buf;      _buf.mtype = 0;        memset (_buf.mtext, ' n ', sizeof (_buf.mtext)); if (MSGRCV (msg_id,&_buf,sizeof (_buf.mtext), recv_type,0) < 0) {printf ("%d:%s", Errno,strerror (errno))          ;      return-1;      } strcpy (Msg_out,_buf.mtext);  return 0;   }


#include "comm.h"    int main ()  {      int msg_id = Creat_msg_queue ();      if (msg_id <0)      {          printf ("%d:%s\n", Errno,strerror (errno));          return 1;      }        Char Buf[_size_];      while (1)      {          memset (buf, ' n ', sizeof (BUF));          Recv_msg (MSG_ID,CLIENT_TYPE,BUF);          printf ("client:%s\n", buf);          if (strcasecmp (buf, "quit") = = 0)          {break              ;          }            printf ("Client say Done,please enter#");          Fflush (stdout);          ssize_t _s = Read (0,buf,sizeof (BUF)-1);          if (_s > 0)          {              Buf[_s-1] = ' + ';          }            Send_msg (MSG_ID,SERVER_TYPE,BUF);        }        Destroy_queue (msg_id);      return 0;  }  


#include "comm.h"    int main ()  {      int msg_id = Get_msg_queue ();        Char Buf[_size_];      while (1)      {          printf ("Please Enter:");          Fflush (stdout);          ssize_t _s = Read (0,buf,sizeof (BUF)-1);          if (_s >0)          {              Buf[_s-1] = ' + ';          }          Send_msg (MSG_ID,CLIENT_TYPE,BUF);          if (strcasecmp (buf, "quit") = = 0)          {break              ;          }            memset (buf, ' n ', sizeof (BUF));          Recv_msg (MSG_ID,SERVER_TYPE,BUF);          printf ("server#%s\n", buf);      }        return 0;  }  

★makefile File Writing:

. Phony:all
All:client Server

client:client.c comm.c//gcc-o [email protected] (destination file) $^ (dependency: all content after)
Gcc-o [email protected] $^
Gcc-o [email protected] $^

. Phony:clean
Rm-f Server Client

Note: The five interface functions in comm.h:

①int Creat_msg_queue (); Create a message queue
②int Get_msg_queue (); Get the message queue msg_id

③int send_msg (int msg_id,int send_type,const char* msg); Send Message
④int recv_msg (int msg_id,int recv_type,char* msg_out); Receiving messages

⑤int destroy_queue (int msg_id); Destroy queue

interprocess communication (IPC) Message Queuing

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: 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.