Joke Collection Website - Blessing messages - How to realize message queuing function on Linux with JAVA

How to realize message queuing function on Linux with JAVA

Let's discuss how to communicate between processes without message queues. Message queues have many similarities with named pipes. For more information about named pipes, please refer to my other article: Linux interprocess communication-using named pipes.

What is Message Queuing?

Message Queuing provides a way to send data blocks from one process to another. Each data block is considered to contain one type, and the receiving process can independently receive data structures containing different types. We can avoid synchronization and blocking problems of named pipes by sending messages. But like named pipes, message queues have a maximum length limit for each data block.

Linux uses macros MSGMAX and MSGMNB to limit the maximum length of messages and queues.

Second, using message queues in Linux.

Linux provides a series of function interfaces of message queues, which is convenient for us to use it to realize communication between processes. Its usage is similar to the other two System V PIC mechanisms, namely semaphore and * * * shared memory.

1, msgget function

This function is used to create and access message queues. Its prototype is:

int msgget(key_t,key,int msg flg);

Like other IPC mechanisms, a program must provide a key to name a specific message queue. Msgflg is a permission flag, which indicates the access right of the message queue, which is the same as the access right of the file. Msgflg can OR with IPC_CREAT, which means to create a message queue when the message queue named by key does not exist. If there is a message queue named by key, the IPC_CREAT flag will be ignored and only an identifier will be returned.

It returns the identifier (non-zero integer) of the message queue named key, or-1 if it fails.

2.msgsnd function

This function is used to add a message 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 the message to be sent, but the data structure of the message has certain requirements. The message structure pointed to by the pointer msg_ptr must start with a long integer member variable, which will be used by the receiving function to determine the message type. Therefore, the message structure should be defined as follows:

Construct my message {

Long integer message _ type

/* Data you want to transfer */

};

Msg_sz is the message length pointed by msg_ptr. Note that it is the length of the message, not the length of the whole structure, that is, msg_sz is the length excluding long message type member variables.

Msgflg is used to control what happens when the current message queue is full or the queued messages reach the system-wide limit.

If the call is successful, a copy of the message data is put into the message queue and 0 is returned; if the call fails,-1 is returned.

3.msgrcv function

This function is used to get messages from the message queue, and its prototype is

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

The functions of msgid, msg _ ptr and msg _ ST are the same as those of msgsnd.

Msgtype can realize simple receiving priority. If msgtype is 0, the first message in the queue is obtained. If its value is greater than zero, the first message with the same message type will be obtained. If less than zero, get the first message whose type is equal to or less than the absolute value of msgtype.

Msgflg is used to control what happens when there is no corresponding type of message to receive in the queue.

When the call is successful, the function returns the number of bytes put into the receiving buffer, the message is copied to the user-allocated buffer pointed by msg_ptr, and then the corresponding message in the message queue is deleted. Returns-1 on failure.

4.msgctl function

This function is used to control the message queue. It is similar to the shmctl function with * * * memory. Its prototype is:

int msgctl(int msgid,int command,struct msgid _ ds * buf);

A command is an operation to be taken, and it can have three values.

IPC_STAT: Set the data in the msgid_ds structure as the current associated value of the message queue, that is, overwrite the value of msgid_ds with the current associated value of the message queue.

IPC_SET: If the process has sufficient rights, set the current correlation value of the message queue to the value given in the msgid_ds structure.

IPC_RMID: delete message queue

Buf is a pointer to the structure of msgid_ds, which points to the structure of message queuing mode and access rights. The msgid_ds structure includes at least the following members:

Structure msgid_ds

{

uid _ t shm _ perm.uid

uid _ t shm _ perm.gid

mode _ t shm _ perm.mode

};

Returns 0 on success and-1 on failure.

Thirdly, message queues are used for inter-process communication.

After introducing the definition of message queue and the available interfaces, let's see how it enables processes to communicate. Because unrelated processes can communicate with each other, we will write two programs here, msgreceive and msgsned, to indicate receiving and sending information. Under normal circumstances, we allow both programs to create messages, but only after the receiver receives the last message will it be deleted.

The source file of the program receiving information is msgreceive.c, and the source code is:

# include & ltunistd.h & gt

# include & ltstdlib.h & gt

# include & ltstdio.h & gt

# include & ltstring.h & gt

# include & lt error number & gt

# include & ltsys/msg . h & gt;

Structure message _st

{

Long message type;

char text[BUFSIZ];

};

int main()

{

int running = 1;

int msgid =- 1;

Struct msg_st data;

long int msg type = 0; //Note 1

//Establish a message queue

msgid = msgget((key_t) 1234,0666 | IPC _ CREAT);

if(msgid == - 1)

{

Fprintf(stderr, "msgget failed with error: %d\n", errno);

Exit (exit _ failure);

}

//Get the message from the queue until the end message is encountered.

(while running)

{

if(msgrcv(msgid,(void *)& amp; data,BUFSIZ,msgtype,0) == - 1)

{

Fprintf(stderr, "msgrcv failed, error number: %d\n", error number);

Exit (exit _ failure);

}

Printf ("You wrote: %s\n", data.text);

//Encountered the end

if(strncmp(data.text," end ",3) == 0)

Running = 0;

}

//Delete message queue

if(msgctl(msgid,IPC_RMID,0) == - 1)

{

Fprintf(stderr, "msgctl(IPC_RMID) failed \ n");

Exit (exit _ failure);

}

Exit (exit _ success);

}

The source code of the source file msgsend.c of the program that sends the information is:

# include & ltunistd.h & gt

# include & ltstdlib.h & gt

# include & ltstdio.h & gt

# include & ltstring.h & gt

# include & ltsys/msg . h & gt;

# include & lt error number & gt

#define MAX_TEXT 5 12

Structure message _st

{

Long message type;

char TEXT[MAX _ TEXT];

};

int main()

{

int running = 1;

Struct msg_st data;

char buffer[BUFSIZ];

int msgid =- 1;

//Establish a message queue

msgid = msgget((key_t) 1234,0666 | IPC _ CREAT);

if(msgid == - 1)

{

Fprintf(stderr, "msgget failed with error: %d\n", errno);

Exit (exit _ failure);

}

//Write the message to the message queue until it is finished.

(while running)

{

//Input data

Printf ("Enter some text:");

fgets(buffer,BUFSIZ,stdin);

data . msg _ type = 1; //Note 2

strcpy(data.text,buffer);

//Send data to the queue

if(msgsnd(msgid,(void *)& amp; data,MAX_TEXT,0) == - 1)

{

Fprintf(stderr, "msgsnd failed \ n");

Exit (exit _ failure);

}

//Enter end to end the input.

if(strncmp(buffer," end ",3) == 0)

Running = 0;

Sleep (1);

}

Exit (exit _ success);

}

Reprinted for reference only, the copyright belongs to the original author. Have a nice day. Please accept it if you are satisfied.