Message queue
Pipes and shared memory: byte stream data
Message: datagram (type + data)
Queues: priority queues
You can specify the type to read. Under the same type, it is in the order of first in first out
Operation of message queue:
1. Create and access a message queue
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflag);
- key: the name of a message queue. Just give an integer value
- msgflag: there are two options IPC_CREAT and IPC_EXCL, IPC alone_ Creat: if the message queue does not exist, it will be created. If it does exist, it will be opened and returned; Use IPC alone_ Excl is meaningless; Both are used at the same time. If the message queue does not exist, it will be created. If it does exist, an error will be returned.
- Return value: a non negative integer is returned successfully, that is, the identification code of the message queue. If it fails, it returns - 1
2. Add a message to the message queue
int msgsnd(int msqid, const void *msqp, size_t msqsz, int msqflg);
- msgid: the message queue identifier returned by the msgget function
- msqp: pointer to the message to be sent
- msqsz: the size of the data part in the message structure, excluding the type size
- msgflg: the default is 0
- Return value: 0 for success and - 1 for failure
On the one hand, the message structure must be less than the upper limit specified by the system. On the other hand, it must start with a long int long integer. The receiver uses this to determine the type of message
struct msgbuf { long mtye; //Message type, must be greater than 0 char mtext[1]; //Message data };
3. Accept messages from a message queue
ssize_t msgrcv(int msqid, void *msqp, size_t msqsz, long msqtyp, int msqflg);
Parameters: same as msgsnd
Return value: the number of characters actually put into the receiving buffer is returned successfully, and - 1 is returned in case of failure
If the specified space cannot completely store the data of the message, the reading is unsuccessful
4. Control function of message queue
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
- msqid: the message queue identifier returned by the msgget function
- cmd: there are three optional values
IPC_STAT msqid_ The data in DS structure is set as the current association value of message queue
IPC_SET sets the current association value of the message queue to msqid on the premise that the process has sufficient permissions_ The value given in the DS data structure
IPC_RMID delete message queue
- Return value: 0 for success and - 1 for failure
As before, we write two programs. a writes data to the message queue and b reads data from the message queue.
Complete the following:
Send three consecutive messages first:
Then, after receiving two messages in succession, it is found that the last message remains in the message queue:
Once the message in the message queue is read or the non-existent message, such as type 2 message, is read, the terminal displays the blocking state
Note: when receiving a message, if the message type is changed to 0, it does not mean that the message No. 0 is received. Instead, the message type is not distinguished. It is received directly and finally used by the recipient
msg.h
#program once typedef struct msgbuf { long mtype; char mtext[128]; }MsgBuf;
send out
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<assert.h> #include<unistd.h> #include<sys/types.h> #include<sys/ipc.h> #include<sys/msg.h> #include"msg.h" int main(int argc,char *argv[]) { //argv[1]:type //argv[2]:data if(argc < 3) { printf("Please input type and data\n"); exit(0); } MsgBuf mess; memset(&mess,0,sizeof(mess)); sscanf(argv[1],"%d",&mss.mtype); strcpy(msss.mtext,argv[2]); int msgid = msgget((key_t)1234,IPC_CREAT | 0664); assert(msgid != -1); msgsnd(msgid,&mess,strlen(mess,mtext),0); exit(0); }
Receive (note the reading problem)
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<assert.h> #include<unistd.h> #include<sys/types.h> #include<sys/ipc.h> #include<sys/msg.h> #include"msg.h" int main(int argc,char *argv[]) { if(argc < 2) { printf("please input type\n"); exit(0); } MsgBuf mess; memset(&mess,0,sizeof(mess)); long type = 0; sscanf(argv[1],"%d",&type); int msgid = msgget((key_t)1234,IPC_CREAT | 0664); assert(msgid != -1); msgrcv(msgid,&mess,127,type,0);//Change to 5 to see the result and intercept the message printf("type:%d,data :%s\n",mess.mtype,mess.mtext); exit(0); }
Brief summary: