Implementation of Message Queuing

Source: Internet
Author: User

First, what is Message Queuing
Message Queuing provides a way to send a block of data from one process to another. Each block of data is considered to contain a type, and the receiving process can independently receive data structures that contain different types.
Ii. using Message Queuing in Linux
Linux provides a series of function interfaces for Message Queuing that allow us to easily use it for interprocess communication. Its usage is similar to the other two system V pic mechanisms, i.e. semaphores and shared memory.

1. Msgget function
This function is used to create and access a message queue. Its prototype is:

int Msgget (key_t, key, int msgflg);

Like other IPC mechanisms, a program must provide a key to name a particular message queue. MSGFLG is a permission flag that represents the access rights for Message Queuing, which is the same as file access. MSGFLG can be done or manipulated with ipc_creat, which means that when a message queue named by key is not present, a message queue is created, and if a message queue named by key is present, the IPC_CREAT flag is ignored and only one identifier is returned.

It returns an identifier for a message queue named key (nonzero integer), which returns 1 on failure.

2. msgsnd function
This function is used to add messages to the message queue. Its prototype is:

int msgsend (int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);

MsgId is the message queue identifier returned by the Msgget function.

Msg_ptr is a pointer to prepare to send a message, but the data structure of the message has certain requirements, the pointer msg_ptr the message structure must be a long integer member variable start structure, the receive function will use this member to determine the type of message. So the message structure should be defined like this:


struct my_message{
long int message_type;
/* The data wish to transfer*/
};

MSG_SZ is the length of the message that the MSG_PTR points to, note the length of the message, not the length of the entire struct, that is, the length of the member variable that MSG_SZ does not include the long integer message type.

The MSGFLG is used to control what will happen when the current message queue is full or the queue message reaches the system-wide limit.

If the call succeeds, a single copy of the message data is placed in the message queue and returns 0, returning 1 on failure.

3. Msgrcv function
This function is used to get the message from a message queue, and its prototype is

int MSGRCV (int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);

MsgId, Msg_ptr, Msg_st functions as function msgsnd functions.

The Msgtype can implement a simple receive priority. If Msgtype is 0, it gets the first message in the queue. If its value is greater than 0, it gets the first information with the same message type. If it is less than 0, it gets the first message with a type equal to or less than the absolute value of Msgtype.

The MSGFLG is used to control what happens when there are no corresponding types of messages in the queue that can be received.

When the call succeeds, the function returns the number of bytes placed in the receive buffer, the message is copied to the user-allocated buffer that is pointed to by msg_ptr, and the corresponding message in the message queue is deleted. Returns-1 on failure.

4. Msgctl function
This function is used to control Message Queuing, which is similar to the SHMCTL function of shared memory, and its prototype is:

int msgctl (int msgid, int command, struct msgid_ds *buf);

command is the action that will be taken, it can take 3 values,
Ipc_stat: Sets the data in the MSGID_DS structure to the current associated value of the message queue, which overwrites the value of Msgid_ds with the current association value of the message queue.
Ipc_set: If the process has sufficient permissions, set the current association value for the message queue to the value given in the MSGID_DS structure
IPC_RMID: Deleting Message Queuing

BUF is a pointer to the MSGID_DS structure that points to the structure of the Message Queuing pattern and access rights. The MSGID_DS structure includes at least the following members:


struct MSGID_DS
{
uid_t Shm_perm.uid;
uid_t Shm_perm.gid;
mode_t Shm_perm.mode;
};

Returns 0 on success, 1 on failure.

Iii. using Message Queuing for interprocess communication
The code is implemented as follows:
Comm.h

#ifndef  _COMM_#define _COMM_#include<stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/msg.h> #include <sys/types.h> #include <string.h> #define  _msg_size_ 1024# define path  "." #define  proj_id 0x777#define _ser_msg_type_ 1#define _cli_msg_type_ 2struct  msgbuf{    long mtype;    char mtext[_MSG_SIZE_];}; Static int comm_msg (Int flag); Int creat_msg_queue (); Int get_msg_queue (); int send _msg_queue (Int _msg_id,const char* msg,long type); Int recv_msg_queue (int _msg_id , Char* msg,long type); Int destroy_msg_queue (int _msg_id); #endifcomm. C#include "comm.h" const  int _ser_send_type=1;//serverconst int _cli_send_type=2;//clientstatic int comm _msg (Int flag) {    key_t _key=ftok (path,proj_id);    if (_key<0) {        perror ("Ftok");         return -1;    }    int _msg_id=msgget (_key , flag);     if (_msg_id<0) {        perror ("Msgget ");        return -1;    }     else        return _msg_id;} Int creat_msg_queue () {    umask (0);     return comm_msg (IPC_ Creat| ipc_excl|0666);} Int get_msg_queue () {    return comm_msg (ipc_creat);} Int send_msg_queue (Int _msg_id,const char* message,long type) {     struct msgbuf msg;    msg.mtype=type;    strcpy ( Msg.mtext,message);     if (Msgsnd (_MSG_ID,&AMp;msg,strlen (Msg.mtext), 0) <0)     {         Perror ("msgsnd");         return -1;    }     return 0;} Int recv_msg_queue (Int _msg_id,char* msg,long type) {    struct  Msgbuf ret;    memset (Ret.mtext, ' _msg_size_ ');     if (MSGRCV (_ msg_id,&ret,_msg_size_-1,type,0) <0)     {         perror ("MSGRCV");        return -1;     }    strcpy (msg,ret.mtext);     return 0;} Int destroy (int _msg_id) {    if ( msgctl (_msg_id,ipc_rmid,null) <0)      {        perror ("Msgctl");          return -1;    }    else    {         printf ("remove msg_queue\n");         return 0;    }}msg_client.c#include "Comm.h" Int main () {     int _msg_id=creat_msg_queue ();     if (_msg_id<0)      {        exit (1);    }     char msg_buf[_msg_size_];    while (1)     {         fflush (stdout);         printf ("\nplease input:>");         memset (Msg_buf, ' n '), _ Msg_size_);         //gets (MSG_BUF);         if (Send_msg_queue (_msg_id,MSG_BUF,_CLI_MSG_TYPE_) <0)         {             printf ("send fail\n");             exit (1);        }         if (Recv_msg_queue (_msg_id,msg_buf,_ser_msg_type_) <0)          {            printf ( "recv fail\n");             exit (1);         }        printf ("server:> %s\n ", msg_buf);     }        return 0;}
Msg_server.c#include "Comm.h" Int main () {    int _msg_id=creat_msg_queue ();     if (_msg_id<0)     {         Exit (1);    }    char msg_buf[_msg_size_];     printf ("input quit endding...\n");     while (1)     {         if (Recv_msg_queue (_msg_id,msg_buf,_cli_msg_type_) <0)          {             printf ("recv fail\n");             exit ( 1);        }        else         {             if (strcmp ("Quit", MSG_BUF) ==0)                  return 0;            printf ("client:>  %s ", Msg_buf);        }         printf ("\ninput:>");         fflush (stdout);         memset (msg_buf, ' _msg_size_ ');         Gets (MSG_BUF);         if (Send_msg_queue (_msg_id,msg_buf,_ser_msg_ TYPE_) <0)         {             printf ("send fail\n");             exit (1);        }    }     destroy (_msg_id);     return 0;} Makefile. phony:allall:client serverclient:msg_client.c  comm.c    gcc -o [ email protected] $^server:msg_server.c  comm.c    gcc -o [ email protected] $^. Phony:cleanclean:    rm -rf client server


Iv. the difference between Message Queuing and pipelines:

Message Queuing is used for inter-process communication, and Linux uses ipcs-q to query Message Queuing. We can avoid the synchronization and blocking problems of named pipes by sending messages. Message Queuing differs from a pipeline in that Message Queuing is message-based, the pipeline is byte-stream-based, and Message Queuing is read first-out. Message Queuing and Named pipes have a kind of not, that is, the maximum length of each message is an upper limit (Msgmax), the total number of bytes per message queue is capped (MSGMNB), the total number of Message Queuing on the system also has an upper limit (Msgmni).

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