消息队列简要概述:
~消息队列就是存放在内核中的链表,不同的进程找到它并且依据它来传输数据(发送或者接受),必须找到同一个链表并且接受和发送的数据类型相同,一个消息队列具有特定的ID号(内核处理);
特点:
~消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级
~消息队列独立于发送和接收,进程结束时其内容并不会消失
~消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取
使用消息队列
~消息队列向关API
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);//创建或者打开消息队列,成功返回ID,失败返回-1
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);//添加消息,失败返回-1
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);//读取消息,失败返回-1
int msgctl(int msqid, int cmd, struct msqid_ds *buf);//控制消息队列,失败返回-1,msgctl函数移除消息队列常用指令为IPC_RMID,最后参数一般为NULl
注:
~msgget函数在两种情况下回创建一个消息队列,如果没有与key值相对应的消息队列,并且flag中包含了IPC_CREAT标志,便会创建一个消息队列。在key值为IPC_PRIVATE使也会重新创建一个消息队列
~msgrcv函数在读取消息是type类型有三种情况:
type == 0 返回队列中第一个消息;
type > 0,返回队列中类型为type的第一个消息
type<0,返回队列中消息类型小于type绝对值的的消息,如果有多个则取最小的;
type非0是消息队列采取非先进先出的次序读消息。
~注:系统建立IPC通讯(如消息队列,共享内存,信号量时)必须要指定一个ID号,通常可以通过ftok()函数获取:
//key_t ftok(char *fname,int id);
//第一个参数是指定的文档名(需要的是文档的索引节点),id是子序号;
key_t key;
key = ftok(".",'z');
printf("key = %x\n",key);
~注:msgsnd和msgrcv函数发送数据;
调用时buf的结构体可以这样定义:
struct msgbuf{
long mtype;
char mtext[128];
};
编程实现两个进程数据交换
#include <string.h>
#include <stdio.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msgbuf{
long mtype;
char mtext[128];
};
int main()
{ int msgid = 0;
struct msgbuf sendbuf = {988,"this is message from quen"};
key_t key;
key = ftok(".",'z');
printf("key = %x\n",key);//16进制打印出id
struct msgbuf readbuf;
msgid = msgget(key,IPC_CREAT|0777);//如果id号为key的消息队列不存在则创造一个消息队列,并且权限为777;
if(msgid == -1){
printf("creat failed!\n");
}
msgsnd(msgid,&sendbuf,strlen(sendbuf.mtext),0);//最后一个参数为type =0 将数据复制到第一个消息
msgrcv(msgid,&readbuf,sizeof(readbuf.mtext),988,0);//最后一个参数读取第一个消息
printf("return from read:%s\n",readbuf.mtext);
//msgctl(msgid,IPC_RMID,NULL);
return 0;
}
读取数据代码如下:
#include <string.h>
#include <stdio.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msgbuf{
long mtype;
char mtext[128];
};
int main()
{
int msgid = 0;
struct msgbuf sendbuf = {988,"thank you"};
key_t key;
key = ftok(".",'z');
printf("key = %x\n",key);
struct msgbuf readbuf;
msgid = msgget(key,IPC_CREAT|0777);
if(msgid == -1){
printf("error\n");
}
msgrcv(msgid,&readbuf,sizeof(readbuf.mtext),988,0);
printf("read from que:%s\n",readbuf.mtext);
msgsnd(msgid,&sendbuf,strlen(sendbuf.mtext),0);
msgctl(msgid,IPC_RMID,NULL);
return 0;
}
添加的指令为:
ls -oc查看文件权限;
ls -i 查看文件索引节点值;