I. Introduction
---- After entering the 1990s, with the development of computer and network technology, many data processing systems use open system architectural client / server network modes. That is, the client proposes the task request, and the server is handled accordingly, performs the requested task, and then returns the result to the client. For example: the bank ATM's front machine and data processing of the data constitutes a client / server mode; this mode structure is also constituted between the telephone bank's front and bank data processing hosts. There are POS, etc. In this way, the request for various applications is very frequent. When the data host is handling a variety of requests, ATM, telephone banking, POS, etc. If there is no corresponding mechanism control, the data will make confusion, it is possible to generate overdraft, and May handle the password changed account.. The integrity of the data is uncontrollable. The message queue is a powerful tool to solve this problem. It makes the host when processing various requests, and ensures the consistency and security of the data according to the order in order.
Second, the basic concept
---- 1. Queue
---- Queue is a linear table of information, and its access order is advanced first out (FIFO). That is to say, the first data item in the queue will be the first time the data item read from the queue, and the second item placed will be the second term read, according to such push. This is the unique access operation allowed by the queue, and other random access is not allowed. Such a data structure ensures that requests for data resources will be strictly in accordance with the order of order, so that the scheduling of the event can be used to function as an I / O buffer.
---- 2. Packet
---- Transfer Process and Receive Process Switching, typically by dividing information into several segments into the data exchange buffer, the processes are communicated by accessing the buffer. Therefore, the data is delivered between processes in discontinuous forms, which are called packets.
---- 3. Message Queue
---- Tissue message queue as a queue structure. This queue is used to store the title information of each packet that is transmitted or received. Each message queue also corresponds to a data structure, which contains information of the message queue, and information such as the current status information of the message queue. Message queues can be "send" and "reception" operations.
Third, the programming point and operation process of the message queue
---- 1. Creation of the message queue
---- Before the message can send and receive, you must create a unique message queue and data structure. This created unique identifier is called a message queue descriptor (MSQID), used to identify or quote Message queue and data structure. Use the Msgget (Longkey, INTMSGFLG) system call to create a message queue, where Key is a long integer, which can be obtained by user settings or by FTOK (). The value of MSGFLG is the combination of octal message queue operations and control commands. The operation is defined as:
Operation allows the right eight-enrichment integer
User readable 0400
Users can write 0200
The same group readable 0040
The same group can write 0020
Other readable 0004
Other writable 0002
---- Operational rights can be derived, such as users can "read", "write" permissions are 0400 | 0200 = 0600. The control command can take IPC_CREAT or IPC_EXCL. If you want to create a key = 888 and the owner and the group-readable message queue, do the following system calls Msgget (0x888,0660 | ipc_creat). You can use the IPCS command to see the following information after you created:
IPCSTATUSFROM / DEV / MEMASOFSUN
Jan 2506: 49: 521970
TidKeyModeownergroup
MessageQueues:
.q70x00000888 - rw-rw ------
Rootsystem
...
---- Its message queue descriptor is 7. The host is root, the same group is System, the access rights is the owner, the user can read. If you perform MSGGET (0x888,0660 | ipc_creat), the message queue corresponding to 0x888 has existed, then the descriptor MSQID of the message queue is returned. ---- 2. Message Send
---- Message Queue Once you created, you can send a message with MSGSND (INTMSQID, VOID * MSGP, SIZE_TMSGSZ, INTMSGFLG). Msgqid is a message queue descriptor created by Msgget, and the MSGP is a pointer to the message segment, which is pointed to contain a message type and a message to send or receive:
StructMsgbuf {
Longmtype; / * Message Type * / CharmText [512];
/ * Message body, 512 is temporarily blamed for the size of the message segment * /
}
---- Msgsz is the length of the character array in the data structure pointed to the MSGP parameter, that is, the packet length, and the maximum value is determined by Msgmax. Msgflg is actions to be taken when the message queue is full (no space in the queue). If MSGFLG & IPC_NOWAIT = is true, the calling process returns immediately and does not send the message. If MSGFLG & IPC_NOWAIT = false, the calling process is suspended, and it is in the "hanging" state and does not send the message. Until one of the following cases: ----- Conditional conditions no longer exist, if the queue is idle, you can send it ----- The consignment queue is removed from the system ----- calling process A signal to be captured, such as an interrupt signal, does not send a message at this time, and the calling process is performed in the manner described in Signal.
---- If the MSGSND returns 0, it is successful. Returns -1 indicates that the transmission fails, and the error type can be specifically view Errno.
---- 3. Receive of messages
---- Use the MSGRCV (INTMSQID, Void * MSGP, SIZE_TMSGSZ, LONGMSGTYP, INTMSGFLG) system to call the structure from the MSQID message queue and put it into the structure of the message segment pointer MSGP. Msgsz gives the number of bytes of MTEXT. If the received message is larger than the MSGSZ and the MSGFLG & MSG_NoError is true, press MSGSZ's size truncation without notify the calling process. MSGTYP Specifies the required message type:
---- MSGTYP = 0 Receive the first message in the message queue ---- MSGTYP> 0 Receive the first packet in the message queue is MsgTyp ---- MSGTYP <0 Receive Message Queue is less than The first message equal to the minimum type of MSGTYP absolute value
---- When there is no desired type of message or message queue on the queue, MSGFLG indicates actions to be taken by the calling process: if msgflg & ipc_nowait is true, the calling process ends and returns -1. If MSGFLG & IPC_NOWAIT is fake, the calling process is suspended until it appears:
---- Add the message of the required type in the queue, call the process to receive the message ----- MSQID message queue from the system deleted ----- Call process receives the captured signal, this time does not receive a message The calling process is performed in the way in Signal described.
---- If the MSGREV is successful, return the number of bytes placed in MTEXT, failed to return -1, and the error type can check errno.
---- 4. Message queue control and revoking
---- Call the control of the message queue with the MSGCTL (INTMSQID, INTCMD, STRUCTMSQID_DS * BUF) system. Msgqid must be a message queue descriptor created with msgget. CMD can be:
---- IPC_STAT View the status of the message queue, the result is placed in the structure of the BUF pointer ---- IPC_SET Set the master ID, the same group identity, operation allowed for the message queue, maximum number of bytes ---- IPC_rmid delete Specified MSQID and related message queues and structures
Fourth, programming example
---- The following is given an instance of using a message queue to implement process communication. The following procedures are all debugged on the IBMRS / 6000 mini-machine (AIX operating system) and IBMPC (UNIX operating system). The program mainly simulates the process of querying the balance based on the account. Including three aspects:
The request process reads an account from the standard input and sends the account to the service process through the message queue;
After the service process receives the account, enter the name and balance of the account on the standard input in the standard input in the order, and return the results to the customer process;
The request process receives the returned information and outputs the result output on the standard output. ---- Service Process (Msgcenter) starts with the request process (msgreq). The client process will be carried when the request number is started, and multiple request processes can be started simultaneously.
/ * Request party program msgreq.c * /
#include
#include
#include
#include
#include
Static struct msgbuf1 {
Long mtype; char mText [100];
} SNDBUF, RCVBUF, * MSGP;
EXTERN INT errno;
Main (int Argc, char ** argv)
{Int RTRN, MSQID;
Char Name [10];
Double balance;
IF (argc! = 2) {fprintf (stderr,
"MSGREQ [01-99] / N"); exit (-1);}
IF ((msqid = msgget (0x888, IPC_CREAT | 0660)) == -1) {
FPRINTF (stderr, "msgget 888 failed! / n"); exit (-1);
}
MSGP = & SNDBUF;
Sprintf (SNDBUF.MTEXT, "% 2.2s", argv [1]);
Printf ("Enter 4-digit account:");
Scanf ("% s", & sndbuf.mtext [2]);
SNDBUF.MTEXT [6] = 0;
Msgp-> mtype = 666;
RTRN = MSGSND (MSQID, MSGP, Strlen (SNDBUF.MTEXT), 0);
IF (RTRN == - 1) {
PERROR ("msgsnd"); exit (-1);
}
Msgp = & rcvbuf;
FPRINTF (stderr, "waiting for the background data processing process to answer ....");
RTRN = MSGRCV (MSQID, MSGP, 100, ATOI (Argv [1]), 0);
IF (RTRN == - 1) {PERROR ("MSGRCV"); exit (-1);}
SSCANF (RCVBUF.MTEXT, "% [^ |] |% LF", Name, & Balance);
Printf ("/ n Name =% S / N", Name);
Printf ("balance =% lf / n", balance);
}
/ * Services program msgcenter.c * /
#include
#include
#include
#include
#include
Static struct msgbuf1 {
Long mtype;
Char mtext [100];
} SNDBUF, RCVBUF, * MSGP;
EXTERN INT errno;
Main ()
{int RTRN, MSGQID;
CHAR STRBUF [100];
IF ((msqid = msgget (0x888, IPC_creat | 0600)) == -1) {
FPRINTF (stderr, "msgget 888 failed! / n"); exit (-1);
}
While (1) {
Msgp = & rcvbuf;
FPRINTF (stderr, "waiting for the reception process ...");
RTRN = MSGRCV (MSQID, MSGP, 100, 666, MSG_NoError);
IF (RTRN == - 1) {PERROR ("MSGRCV"); exit (-1);}
MSGP = & SNDBUF;
Sprintf (strbuf, "% 2.2s / 0", rcvbuf.mtext);
Msgp-> mtype = atoi (strbuf);
Printf ("/ n Enter account =% 4.4S account name:", & rcvbuf.mtext [2]);
Scanf ("% s", SNDBUF.MTEXT);
STRCAT (SNDBUF.MTEXT, "|");
Printf ("Enter the account balance:");
Scanf ("% s", strbuf);
STRCAT (SNDBUF.MTEXT, STRBUF);
RTRN = MSGSND (MSQID, MSGP, Strlen (SNDBUF.MTEXT), 0);
IF (RTRN == - 1) {PERROR ("msgsnd"); exit (-1);}
}
}