1、消息队列是什么?
消息队列是在内核空间内部的一个链表。通过Linux内核在各个进程间传递消息。
要获取对应的消息队列,每一个消息队列都有一个唯一的表示符来区分。
2、怎么样使用消息队列进行进程间通讯?
1)先产生一个标示符
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
pathname :这个路径必须是一个存在的、可访问的的文件
proj_id :必须是一个非零的数字,然后通过这个函数就会产生一个key_t类型的标示符。
返回值:成功就会返回 对应的key值,错误返回-1,并且可以把对应的错误码打印出来看一下是什么错误。
2)通过这个key去创建消息队列
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
第一个参数,第一个参数就是我们第一步通过ftok产生的key值,用来标识唯一的消息队列。
第二个参数,分为有两种
第一种情况:创建 IPC_CREAT | 权限位 例如: IPC_CREAT | 0664
第二种情况:打开 0
返回值:成功返回的是消息队列的ID,如果失败了,返回-1,并且错误码可以通过perror打印出来。
3)通过收发的函数,实现收发,实现进程间通讯。
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
msqid:这个参数就是消息队列的ID,表示我们要把消息发送到哪个队列,或者从哪个队列来接受消息。
msgp:这个是指针,指向我们所需要发送的消息,消息我们可以自定义。
struct msgbuf {
long mtype; /* message type, must be > 0 消息的类型,这个参数是自己定义 */
char mtext[1]; /* message data 这个是我们需要发送的消息的具体数据 */
};
msgsz :消息内容的长度,是对应mtext的实际大小。
msgflg:
1)IPC_NOWAIT 不阻塞的模式。
2)0 阻塞模式发送(一般都是用这个)
返回值:成功返回0,失败的话返回-1,并且可以把对应的错误码打印出来。
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
这个函数的作用,就是在指定的消息队列里面,把消息摘下来,拷贝到msgp所指定buffer里面。
msqid:这个参数就是消息队列的ID,表示我们要把消息发送到哪个队列,或者从哪个队列来接受消息。
msgp:这个是指针,指向我们所需要接收的消息的buffer,
msgsz:指的是消息的最大的长度,消息内容的长度,是对应mtext的实际大小。
msgtyp:指的是消息的类型,0代表读取的是队列内第一个消息。如果是大于零的时候,队列里面第一个msgtyp类型的消息就会被读回来。
msgflg:
1)IPC_NOWAIT 不阻塞的模式。
2)0 阻塞模式发送(一般都是用这个)
返回值:成功的话,返回的是,对应mtext的实际大小(实际消息的长度), 失败的话返回-1,并且可以把对应的错误码打印出来。
4)用于控制这个消息队列,比如说删除队列。
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
msqid:这个参数就是消息队列的ID
cmd: 一些命令,常用的有删除队列的命令:IPC_RMID
msqid_ds *buf ,关于队列的一些信息的描述。
今日程序:
#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdio.h>
#include<string.h>
struct msgbuf
{
long mytype;
char mtext[256];
};
int main()
{
int msgid;
key_t key;
struct msgbuf msg,msgr;
key = ftok("/home/gec",111);
if(key < 0)
{
perror("ftok fail\n");
exit(-1);
}
printf("key = %d\n",key);
msgid = msgget(key,IPC_CREAT|0777);
if(msgid < 0)
{
perror("msgget fail");
exit(-1);
}
msg.mytype = 888;
while(1)
{
printf("A说:");
memset(msg.mtext,0,strlen(msg.mtext));
scanf("%s",msg.mtext);
msgsnd(msgid,&msg,256,0);
msgrcv(msgid,&msgr,256,888,0);
printf("B回应说:%s\n",msgr.mtext);
}
return 0;
}
/////////////////////////////////////////////////////////////////
#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdio.h>
#include<string.h>
struct msgbuf
{
long mytype;
char mtext[256];
};
int main()
{
int msgid;
key_t key;
struct msgbuf msg,msgr;
key = ftok("/home/gec",111);
if(key < 0)
{
perror("ftok fail\n");
exit(-1);
}
printf("key = %d\n",key);
msgid = msgget(key,IPC_CREAT|0777);
if(msgid < 0)
{
perror("msgget fail");
exit(-1);
}
msg.mytype = 888;
while(1)
{
msgrcv(msgid,&msg,256,888,0);
printf("A回应说:%s\n",msgr.mtext);
printf("B说:");
memset(msgr.mtext,0,strlen(msgr.mtext));
scanf("%s",msgr.mtext);
msgsnd(msgid,&msg,256,0);
}
return 0;
}