进程通信IPC----消息队列

  1. 往消息队列中发送消息,消息的类型如结构体Msg所示:
#include<sys/types.h>
#include <sys/msg.h>
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>

typedef struct 
{
	long type;
	char name[20];
	int age;
}Msg;

int main(int argc, char const *argv[])
{
	key_t key = ftok("/home/test/msgq",'8');
	int msgid = msgget(key, IPC_CREAT|O_WRONLY|0777);
	printf("send-key:%x , msgid:%d\n",key,msgid);
	if (msgid < 0)
	{
		perror("msgget error!");
		exit(-1);
	}
	Msg m;
	while(1){
		 memset(&m,0,sizeof(m));
		 puts("please input your type name age:");
		 scanf("%ld%s%d",&m.type, m.name,&m.age);
		 msgsnd(msgid, &m,sizeof(m) - sizeof(m.type),0);
	}
	msgctl(msgid,IPC_RMID,NULL);
	return 0;
}
  1. 从消息队列中读取数据
#include<sys/types.h>
#include <sys/msg.h>
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>

typedef struct{
    long type;
    char name[20];
    int age;
}Msg;

int main(int argc, char const *argv[])
{
	//该路径可以随便设置,但是发送接收两端保持一致即可
	//该路径是必须存在的,ftok只是根据文件inode在系统内的唯一性来取一个数值,和文件的权限无关。
	//proj_id是可以根据自己的约定,随意设置。这个数字,有的称之为project ID; 在UNIX系统上,它的取值是1到255
	key_t key = ftok("/home/test/msgq",'8');
	int msgid = msgget(key,O_RDONLY);
	printf("read-key:%x , msgid:%d\n",key,msgid);
    if(msgid<0)
    {   
        perror("msgget error!");
        exit(-1);
    }
    Msg rcv;
    long type;
    ssize_t result = 0;
    while(1){
    	memset(&rcv, 0, sizeof(rcv));
    	puts("please input type you want!");
    	scanf("%ld",&type);
    	result = msgrcv(msgid,&rcv, sizeof(rcv) - sizeof(type), type, IPC_NOWAIT);
    	printf("result=:%d\n", result );
    	//读取不到,立马返回,返回-1,不会一直阻塞. 
    	//如果把 IPC_NOWAIT改成0,msgrcv会一直阻塞,知道队列中有该条消息才往下执行
    	if (result == -1)
    	{
    		printf("there is no msg what you want, pls check again\n");
    		continue;
    	}
    	printf("rcv--name:%s age:%d\n",rcv.name,rcv.age);
    }
    msgctl(msgid,IPC_RMID,NULL);

	return 0;
}

A: 如下截图往消息队列中发送了3条消息
进程通信IPC----消息队列
B: 然后从消息队列中可以根据消息类型读取(可以指定消息类型读取,没有顺序,每条消息只能读取一次,重复读取或者读取不存在的消息msgrcv(最后一个参数设定为IPC_NOWAIT)将会返回-1)
进程通信IPC----消息队列

C: 通过ipcs 查看消息队列,其中key和msgid跟代码打印的log保持一致.
进程通信IPC----消息队列

D: 如果此时此时 ipcrm -q 1048576 或者 ipcrm -Q 0xffffffff ,则内核队列会删除,此时再次运行对应的程序,由于两者之间建立的消息通道已经被删除,所以无法再次建立通信了

E: 经测试发现ftok第一个参数: 该文件路径/home/test/msgq 不一定真实存在,但是发送端和接收端必须保持一致.

上一篇:实验八 进程间通信


下一篇:SV -- Interprocess Communication (IPC 线程间通信)