进程通信3-消息队列

消息队列和之前的管道还有共享内存几乎是一个性质,三种通信都需要获得一块东西,然后通过这个东西通信。
命名管道:mkfifo创建一个带名字的管道,然后进程open进来
消息队列:msgget创建一个消息队列,然后进程也是msgget进来,只是他发的消息是结构体形式,第一个参数用来当标识,就好比一个储物间,有很多柜子放东西,这个第一个参数就是标记几号柜子的,然后你想从几号柜子取就填几号。
共享内存:shmget创建共享内存,然后进程shmat进来通信
代码实现:
//创建消息队列

int msgget(key_t key, int msgflg);

//发送消息

int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);

//接收消息

int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);

//控制队列-通常拿来销毁队列

int msgctl(int msgid, int command, struct msgid_ds *buf);

send.cpp


#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/msg.h>
#include <errno.h>
 
#define MAX_TEXT 512
struct msg_st
{
    
    
	long int msg_type;
	char text[MAX_TEXT];
};
 
int main()
{
    
    
	int running = 1;
	struct msg_st data;
	char buffer[BUFSIZ];
	int msgid = -1;
 
	//建立消息队列
	msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
	if(msgid == -1)
	{
    
    
		fprintf(stderr, "msgget failed with error: %d\n", errno);
		exit(EXIT_FAILURE);
	}
 
	//向消息队列中写消息,直到写入end
	while(running)
	{
    
    
		//输入数据
		printf("Enter some text: ");
		fgets(buffer, BUFSIZ, stdin);
		data.msg_type = 1;    //注意2
		strcpy(data.text, buffer);
		//向队列发送数据
		if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)
		{
    
    
			fprintf(stderr, "msgsnd failed\n");
			exit(EXIT_FAILURE);
		}
		//输入end结束输入
		if(strncmp(buffer, "end", 3) == 0)
			running = 0;
		sleep(1);
	}
	exit(EXIT_SUCCESS);
}

recv.cpp

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/msg.h>
 
struct msg_st
{
    
    
	long int msg_type;
	char text[BUFSIZ];
};
 
int main()
{
    
    
	int running = 1;
	int msgid = -1;
	struct msg_st data;
	long int msgtype = 0; //注意1
 
	//建立消息队列
	msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
	if(msgid == -1)
	{
    
    
		fprintf(stderr, "msgget failed with error: %d\n", errno);
		exit(EXIT_FAILURE);
	}
	//从队列中获取消息,直到遇到end消息为止
	while(running)
	{
    
    
		if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1)
		{
    
    
			fprintf(stderr, "msgrcv failed with errno: %d\n", errno);
			exit(EXIT_FAILURE);
		}
		printf("You wrote: %s\n",data.text);
		//遇到end结束
		if(strncmp(data.text, "end", 3) == 0)
			running = 0;
	}
	//删除消息队列
	if(msgctl(msgid, IPC_RMID, 0) == -1)
	{
    
    
		fprintf(stderr, "msgctl(IPC_RMID) failed\n");
		exit(EXIT_FAILURE);
	}
	exit(EXIT_SUCCESS);
}

在这里插入图片描述
在这里插入图片描述

Guess you like

Origin blog.csdn.net/qq_40861091/article/details/102262841