Linux interprocess communication|message queue

message queue

1. Overview of Message Queuing

The message queue is a list of some messages. Users can add messages and read messages in the message queue. Message queue has certain FIFO characteristics, but it can realize random query of messages, which has greater advantages than FIFO. At the same time, these message advantages exist in the kernel and are identified by the "queue ID".

2. Message queue programming

2.1 Programming instructions

The realization of the message queue includes the following 4 operations:

  • To create or open a message queue, use the msgget() function
  • To add a message, use the msgsnd() function
  • To read the message, use the msgrcv() function
  • To control the message queue, use the msgctl() function
2.2 Function introduction

msgget() function

/*****msgget()函数*****/
函数原型:int msgget(key_t key, int msgflg)
传 入 值:key 消息队列的键值,多个进程可通过它访问同一个消息队列。IPC_PRIVATE用于创建私有消息队列
		 msgflg 权限标志位
返 回 值:成功:消息队列ID;
		 失败:返回-1

msgsnd() function

/*****msgsnd()函数*****/
函数原型:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)
传 入 值:msqid 消息队列的队列ID
		 msgp 指向消息结构的指针
		 msgsz 消息正文的字节数
		 msgflg 若为0表示调用阻塞直到发送成功为止;IPC_NOWAIT表示若消息无法立即发送,函数会立即返回
返 回 值:成功:返回0;失败:返回-1

//消息结构msgbuf的定义
struct msgbuf{
    
    
	long mtype;		//消息类型,该结构必须从这个域开始
	char mtext[1];	//消息正文
}

msgrcv() function

/*****msgrcv()函数*****/
函数原型:int msgrcv(int msgid, void *msgp, size_t msgsz, long int msgtyp, int msgflg)
传 入 值:msqid 消息队列的队列ID
		 msgp 指向消息结构的指针,msgsnd()函数的msgp
		 msgsz 消息正文的字节数
		 msgtyp -->0表示接收消息队列中第一消息;
		 		-->大于0表示接收消息队列中第一个类型为msgtyp的消息;
		 		-->小于0表示接收消息队列中第一个类型值不小于msgtyp绝对值且类型值最小的消息
		 msgflg -->MSG_NOERROR 若返回的消息比msgsz字节多,则消息就会截短到msgsz字节,且不通知消息发送进程;
		 		-->IPC_NOWAIT 若在消息队列中没有相应类型的消息可以接收,则函数立即返回;
		 		-->0 msgsnd()调用阻塞直到接收一条相应类型的消息位置;
返 回 值:成功:返回0
		 失败:返回-1

msgctl() function

/*****msgctl()函数*****/
函数原型:int msgctl(int msgid, int cmd, struct msqid_ds *buf)
传 入 值:msqid 消息队列的队列ID
		 cmd -->IPC_STAT 读取消息队列的数据结构msqid_ds,并将其存储在buf指定的地址中;
		     -->IPC_SET 设置消息队列的数据结构msgid_ds中的ipc_perm域值,这个值取自buf参数;
		 	 -->IPC_RMID 从系统内核中删除消息队列;
		 buf 描述消息队列的msqid_ds结构类型变量
返 回 值:成功:返回0
		 失败:返回-1
2.3 Function examples

The following example shows how to use message queues for communication between two processes (sender and receiver). The message sending end process and the message receiving end process do not need additional synchronization between processes.
The message to the sender code is as follows:

/*****msgsnd.c*****/
//省略头文件
#define BUFFER_SIZE 512

struct message{
    
    
	long msg_type;
	char msg_text[BUFFER_SIZE];
};

int main(){
    
    
	int qid;
	key_t key;
	strcut message msg;

	if((key = ftok(".",'a')) == -1){
    
    
		perror("ftok");
		exit(1);
	}
	
	if((qid = msgget(key, IPC_CREAT|0666)) == -1){
    
    
		perror("msgget");
		exit(1);
	}
	printf("Open queue %d\n",qid);
	while(1){
    
    
		printf("Enter some message to the queue:");
		if((fgets(msg.msg_text,BUFFER_SIZE,stdin)) == NULL){
    
    
			puts("no message");
			exit(1);
		}

		msg.msg_type = getpid();
		if((msgsnd(qid, &msg, strlen(msg.msg_text), 0)) < 0){
    
    
			perror("message posted");
			exit(1);
		}
		if((strncmp(msg.msg_text, "quit", 4)) == 0)
			break;
	}
	exit(0);
}

The code of the receiving end of the message queue is as follows:

/*****msgrcv.c*****/
//省略头文件
#define BUFFER_SIZE 512

struct message{
    
    
	long msg_type;
	char msg_text[BUFFER_SIZE];
};

int main(){
    
    
	int qid;
	key_t key;
	strcut message msg;

	if((key = ftok(".",'a')) == -1){
    
    
		perror("ftok");
		exit(1);
	}
	
	if((qid = msgget(key, IPC_CREAT|0666)) == -1){
    
    
		perror("msgget");
		exit(1);
	}
	printf("Open queue %d\n",qid);
	do{
    
    
		memset(msg.msg_text, 0, BUFFER_SIZE);
		if((msgrcv(qid, (void *)&msg, BUFFER_SIZE, 0, 0)) < 0){
    
    
			perror("msgrcv");
			exit(1);
		}
		printf("The message from process %d : %s",msg.msg_type,msg_msg_text);		
	}while(strncmp(msg.msg_text, "quit", 4));
	
	if((msgctl(qid, IPC_RMID, NULL)) < 0){
    
    
		perror("msgctl");
		exit(1);
	}	
	exit(0);
}

Guess you like

Origin blog.csdn.net/Chuangke_Andy/article/details/108306421