Based on the following ideas, this paper firstly expounds the mechanism of Message Queuing from macroscopic, then elaborates the mechanism with specific code, and finally tries to imagine the potential application of this communication mechanism.
Message Queuing is a simple, efficient way to pass data between two unrelated processes, and she exists independently of the sending process and the acceptance process.
Figure 1 Message Queuing communication mechanism
First of all, look at the mechanism of Message Queuing from a macro perspective. Because Message Queuing exists independently of the process, in order to differentiate between different message queues, Message Queuing needs to be marked with a key value, so that two unrelated processes can send and receive messages through the message queue via a pre-agreed key value. For example, process A sends a message to the key message queue, and process B reads the message from the key message queue. There are four main functions involved in this process:
#include <sys/msg.h> # Message Queuing related functions and data structure header filesintMsgctl (intMsqid,intCmdstructMsqid_ds *buf); # Control Message Queuing functionsintMsgget (key_t Key,intMSGFLG); # Create Message queue, key value uniquely identifies the message queueintMSGRCV (intMsqid,void*msg_ptr, size_t MSG_SZ,Long intMsgtype,intMSGFLG); # Receive MessagesintMSGSND (intMsqid,Const void*msg_ptr, size_t MSG_SZ,intMSGFLG); # Send a message
The following combination of code examples, the above process analysis (detailed analysis see code comments)
# msg1.c Receiving End
#include <stdlib.h>#include<stdio.h>#include<string.h>#include<errno.h>#include<unistd.h>#include<sys/msg.h> # header file containing message queue-related functions and data structuresstructMy_msg_st {Long intMy_msg_type; Charsome_text[bufsiz];}; # Message FormatintMain () {intrunning =1; intMsgId; structMy_msg_st Some_data; Long intMsg_to_receive =0; MsgId= Msgget ((key_t)1234,0666|ipc_creat); # Create a message queue with an identifier of key = 1234, note the consistency of the value between the sender and the receiving endif(MsgId = =-1{fprintf (stderr, "Msgget failed with error:%d\n ", errno); Exit (Exit_failure); }# error Handling: Msgget Call successfully returned message queue identifier, call failed return-1 while(running) {if(Msgrcv (MsgId, (void*) &Some_data, Bufsiz,msg_to_receive,0) == -1{# Receives a message from a message queue if the receive fails to execute if statement and exits fprintf (stderr, "MSGRCV failed with error:%d\n ", errno); Exit (Exit_failure); } printf ("you wrote:%S ", some_data.some_text); if(STRNCMP (Some_data.some_text, "End",3) ==0{# If the received text contains "End", set running to 0, the effect is: Exit while loop running=0; } } if(Msgctl (MsgId, Ipc_rmid,0) == -1{# Delete message queue if delete failed to execute if statement and exit fprintf (stderr, "Msgctl (ipc_rmid) failed\n"); Exit (Exit_failure); } exit (exit_success);}
# msg2.c Send Side
#include <stdlib.h>#include<stdio.h>#include<string.h>#include<errno.h>#include<unistd.h>#include<sys/msg.h>#defineMax_text 512structMy_msg_st {Long intMy_msg_type; Charsome_text[max_text];}; # message format, consistent with receive sideintMain () {intrunning =1; structMy_msg_st Some_data; intMsgId; CharBuffer[bufsiz]; MsgId= Msgget ((key_t)1234,0666|ipc_creat); # creates message queue with message identifier key = 1234. If the queue already exists, the identifier of the queue is returned directly to send and receive messages to the message queueif(MsgId = =-1{fprintf (stderr, "Msgget failed with error:%d\n ", errno); Exit (Exit_failure); }# error handling, same as receiver Msg1 while(running) {printf ("Enter some text:"); Fgets (buffer, bufsiz, stdin); # input text from the console and store it in buffer Some_data.my_msg_type=1; # type padding, in this case no special meaning strcpy (some_data.some_text, buffer); # Copy the buffer data into the Some_textif(Msgsnd (MsgId, (void*) &some_data, Max_text,0) == -1{# Sends a message to Message Queuing if the send fails to execute if statement and exits fprintf (stderr, "msgsnd failed\n"); Exit (Exit_failure); } if(strncmp (Buffer, "end",3) ==0{# If "End" is sent, after sending "end", exit while and end the program running=0; }} exit (Exit_success);}
The following is the result of the console simulation:
$ ./MSG2
Enter some text: Hello
Enter Some text: How is you today?
Enter some text: end
$ ./MSG1
You wrote: Hello
Wrote: How is it today?
You wrote: end
$
Message Queuing potential applications
Fig. 2 Application of Message queue in daemon process
2, if there are three GUI programs, they correspond to process 1, process 2, and process 3 respectively. These three applications all require mouse, keyboard operation, if in each process to join the capture mouse, keyboard operation code, then altogether need three copies of such code, a bit of a waste of resources (memory space). If we will capture the mouse, keyboard operation of the code to make a separate process, the process to a specific message queue to send a captured mouse, keyboard action, the current activation image program can extract the corresponding mouse, keyboard action from the message queue, and then execute subsequent instructions accordingly. In this way, it is possible to extract the common parts of different applications, simplifying the design of the application and designing a more optimized commonality handler.
The sublimation of the potential application of Message Queuing
Some ways to deal with the common parts of a program:
Library: Some of the general functions are implemented as library functions, providing a well-defined excuse for external use; When applications apply these functions, they simply invoke the appropriate interface.
Daemon: The common part of the application is proposed to implement as a daemon, through some kind of communication mechanism to implement the daemon and application information interaction.
Reference: "Linux programming fourth Edition"
Message Queuing for inter-process communication between Linux