Message Queuing is a way to communicate between processes, at first I thought that Message Queuing was like a pipe that connected one process to another, and that only two processes could read and write to each other. In fact, this is wrong, Message Queuing is a system-level, it does not belong to a two processes, it is maintained by the system of a linked list structure. Reading and writing to message queues is an operation on a linked list, which defaults to writing data at one end of the list, reading the data at the other end (first out), and the process to specify a message of some type.
When a message queue is created in a process and is readable and writable, all processes in the system can read and write to it.
1. Open or create a message queue
Prototype: int msgget (key_t key, int msgflg);
Parameters:
1 key: The key value of the message queue.
2) MSGFLG:
Ipc_creat: If the message queue object corresponding to the key does not exist, it is created, otherwise the open operation returns 0.
IPC_EXCL: Returns 1 if the message queue object corresponding to the key does not exist, otherwise opens and returns 0.
Permission control: 0666 means readable and writable, and the above ipc_creat do logic or operation.
return value:
The ID of the message queue that was successfully returned, created, or opened.
Failure returned-1.
Example program: test1.c
The code is as follows |
Copy Code |
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> int main (void) { int msgid; printf ("This is test1!\n");
MsgId = Msgget (1001, 0666| Ipc_creat); printf ("MsgId =%d\n", msgid);
return 0; } Execution results: [Root@server ~]# gcc-o test1 test1.c [Root@server ~]#./test1 This is test1! MsgId = 32768 [Root@server ~]# IPCS ------Shared Memory Segments-------- Key shmid owner perms bytes nattch Status ------Semaphore Arrays-------- Key Semid owner Perms Nsems 0x00000000 0 Root 600 1 ------Message Queues-------- Key Msqid owner perms used-bytes messages 0x000003e9 32768 Root 666 0 0 |
As you can see from the result of the IPCS command, Message Queuing exists in the system after the process that created it exits, stating that Message Queuing is a layer of the system and is not part of a process.
2. Set Message Queuing properties (including deletion)
Prototype: int msgctl (int msqid, int cmd, struct msqid_ds *buf);
Parameters:
1) Msqid: ID of the message queue.
2 cmd: Control command to execute.
Ipc_stat: Read Message Queuing properties. Gets the MSQID_DS structure of this queue and stores it in the BUF-pointing structure.
Ipc_set: Set Message Queuing properties.
Ipc_rmid: Deletes message queues.
Ipc_info: Read Message Queuing basics. This command is equivalent to the IPCS command.
Example program: test2.c
The code is as follows |
Copy Code |
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> int main (void) { int i; printf ("This is test2!\n"); i = Msgctl (32768, Ipc_rmid, NULL);/I know the message ID equals 32768. if (0 = i) { printf ("msq deleted!\n"); } return 0; } Execution results: [Root@server ~]# gcc-o test2 test2.c [Root@server ~]#./test2 This is test2! MSQ deleted! [Root@server ~]# IPCS ------Shared Memory Segments-------- Key shmid owner perms bytes nattch Status ------Semaphore Arrays-------- Key Semid owner Perms Nsems 0x00000000 0 Root 600 1 ------Message Queues-------- |
Key Msqid owner perms used-bytes messages
The original message queue was deleted.
3. Write/Read messages to message queues
Prototype: int msgsnd (int msqid, const void *MSGP, size_t msgsz, int msgflg);
Prototype: ssize_t MSGRCV (int msqid, void *msgp, size_t msgsz, long Msgtyp, int msgflg);
Parameters:
1) Msqid: ID of the message queue.
2) MSGP: A pointer to a message buffer that points to a user-definable generic structure as follows.
struct MYMSG {
Long Mtype;
Char mbuf[1024];
};
3) Msgsz: The size of the message.
4) MSGFLG: can be ipc_nowait or 0, indicating whether the operation is blocked or non-blocking.
Set to Ipc_nowait, in msgsnd (), if the message queue is full, it will not block and return 1 (eagain) immediately.
In MSGRCV (), if the message queue is empty, do not wait and return-1 (enomsg) immediately.
Set to 0, in msgsnd (), the process blocks until (a) there is room to hold the message to be sent, or (b) deletes the queue (return EIDRM) from the system, or (c) captures a signal and returns from the signal handler (returns EINTR).
In MSGRCV (), the process blocks until (a) there is a message of the specified type, or (b) deletes the queue from the system (returns EIDRM), or (c) captures a signal and returns from the signal handler (returns EINTR).
5) Msgtype: For the MSGRCV () function, specify the type of message. is equivalent to a flag bit that distinguishes a message category.
Msgtype = 0, returns the first message in the message queue.
return value:
MSGSND (), successfully returned 0, error return-1.
MSGRCV (), returns the length of the message data section successfully, error returns-1.
Example program: TEST3.C
The code is as follows |
Copy Code |
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> #include <errno.h> typedef struct { Long Mtype; Char mbuf[1024]; }mymsg; int main (void) { int i; int MSGID1, MSGID2; Mymsg Message1, Message2, Message3;
printf ("This is test3!\n");
MSGID1 = Msgget (1002, 0666| ipc_creat);//key 1002 if (Msgid1 < 0) { printf ("Create key=1002 Error, errno=%d\n", errno); Exit (-1); } Msgid2 = Msgget (1003, 0666| ipc_creat);//key 1003 if (Msgid2 < 0) { printf ("Create key=1003 Error, errno=%d\n", errno); Exit (-1); } //initialization message1.mtype = 1;//sets a message type memcpy (Message1.mbuf, "first Messages",) message3.mtype = 1; memcpy (message3.mbuf, "Hello test4.", 12); //test3 process sends a message on the MSGID1 i = msgsnd (MSGID1, (void *) &message1, strlen (MESSAGE1.MBUF) +1 , 0); if (i < 0) { printf ("Send message1 error, errno=%d\n", errno); ex It (-1); } &NBSP //test3 The process from the MSGID1 message to the message2 i = MSGRCV (MSGID1, (void *) &message2, 1024, 0, 0); br> if (i < 0) { printf ("Rev Error, errno=%d\n", errno); exit ( -1); &NBSP} else { //display fetched messages printf ("%s\n", message2.mbuf); .} TEST3 process sends messages on MSGID2 i = msgsnd (Msgid2, (void *) &message3, strlen (message3.mbuf) +1, 0); if (I < 0) { printf ("Send message3 error, errno=%d\n", errno); Exit (-1); }
return 0; } |
Example program: TEST4.C
The code is as follows |
Copy Code |
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> #include <errno.h> typedef struct { Long Mtype; Char mbuf[1024]; }mymsg; int main (void) { int I, J; MYMSG message;
printf ("This is test4!\n");
i = Msgget (1003, 0666| Ipc_creat); if (I < 0) { printf ("Create key=1003 Error, errno=%d\n", errno); Exit (-1); }
The TEST4 process takes messages on key=1003 message queues j = MSGRCV (i, (void *) &message, 1024, 0, 0); if (J < 0) { printf ("Rev Error, errno=%d\n", errno); Exit (-1); } Else { Display the messages taken out printf ("%s\n", message.mbuf); }
return 0; } |
Open two terminals, one executes TEST3 and the other executes test4.
Test3 Execution Results:
The code is as follows |
Copy Code |
[Root@server ~]#./test3 This is test3! The
|
The IPCS command sees a message in the KEY=1003 message queue with a length of 13 bytes.
The code is as follows |
Copy Code |
Key Msqid owner perms used-bytes messages 0x000003ea 98305 Root 666 0 0 0x000003eb 131074 Root 666 13 1 Test4 Execution Results: [Root@server ~]#./test4 This is test4! Hello test4. |
Above.