Linux -- interprocess communication (message queuing)

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:

Keywords: Linux

Added by Thrakorzog on Sat, 05 Mar 2022 11:56:50 +0200