Linux--消息队列(message queue)

消息队列

消息队列是消息的链接表 ,存放在内核中并由消息队列标识符标识。我们将称消息队列为
“队列”,其标识符为“队列 I D”。

msgget()用于创建一个新队列或打开一个现存的队列。msgsnd()用于将新消息添加到队列尾端。每个消息包含一个正长整型类型字段,一个非负长度以及实际数据字节(对应于长度),所有这些都在将消息添加到队列时,传送给msgsnd()msgrcv()用于从队列中取消息。我们并不一定要以先进先出次序取消息,也可以按消息的类型字段取消息

消息队列图示:

消息队列相关函数

ftok函数

key_t ftok(const char *pathname, int proj_id);//“/home/linux” , 'a'

功能:生成一个key(键值)
msgget函数

int msgget(key_t key, int msgflg);

功能:创建或取得一个消息队列对象
返回:消息队列对象的id 同一个key得到同一个对象
格式:msgget(key,flag|mode);
flag:可以是0或者IPC_CREAT(不存在就创建)
mode:同文件权限一样
msgsnd函数

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

功能:将msgp消息写入标识为msgid的消息队列
msgp:
struct msgbuf {
long mtype; /* message type, must be > 0 /消息的类型必须>0
char mtext[1]; /
message data */长度随意
};
msgsz:要发送的消息的大小 不包括消息的类型占用的4个字节
msgflg: 如果是0 当消息队列为满 msgsnd会阻塞
如果是IPC_NOWAIT 当消息队列为满时 不阻塞 立即返回
返回值:成功返回id 失败返回-1
msgrcv函数

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);

功能:从标识符为msgid的消息队列里接收一个指定类型的消息 并 存储于msgp中 读取后 把消息从消息队列中删除
msgtyp:为 0 表示无论什么类型 都可以接收
msgp:存放消息的结构体
msgsz:要接收的消息的大小 不包含消息类型占用的4字节
msgflg:如果是0 标识如果没有指定类型的消息 就一直等待
如果是IPC_NOWAIT 则表示不等待
msgctl函数

int msgctl(int msqid, int cmd, struct msqid_ds *buf);
//eg: msgctl(msgid,IPC_RMID,NULL);//删除消息队列对象

msqid:为消息队列标识符,该值为使用msgget()函数创建消息队列的返回值。
cmd:为执行的控制命令,即要执行的操作。包括以下选项:

  • #define IPC_RMID 0 //删除消息队列
  • #define IPC_SET 1 //设置消息队列属性
  • #define IPC_STAT 2 //读取消息队列属性
  • #define IPC_INFO 3 //读取消息队列基本情况

消息队列练习demo:

write.c

#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<errno.h>
#include<string.h>
#include<fcntl.h>
#include<stdlib.h>

typedef struct{
    long type;
    int len;
    char msg[512];
}MSG;
int main()
{
    key_t key = ftok("/home/test",12);//1.生成键值
    printf("the key:%x\n",key);
    int msgid = msgget(key,IPC_CREAT|O_WRONLY|0777);//2.创建消息队列
    if(msgid < 0)
    {
        perror("msgget error:");
        exit(-1);
    }
    MSG m;
    m.type = 1;
    char *str = "hello i am the writer!";
    strcpy(m.msg,str);
    m.len = strlen(m.msg);
    printf("m.len:%d\n",m.len);
    msgsnd(msgid,&m,sizeof(m)-sizeof(m.type),0);//3.在消息队列中写入消息
    printf("%s\n",m.msg);
    return 0;
}

read.c

#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<errno.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>

typedef struct{
    long type;
    int len;
    char msg[512];
}MSG;

int main()
{
    key_t key = ftok("/home/test",12);//1.生成键值
    printf("the key:%x\n",key);
    int msgid = msgget(key,O_RDONLY);//2.获取消息队列对象
    if(msgid < 0)
    {
        perror("msgget error");
        exit(-1);
    }

    MSG m;
    m.type = 1;
    msgrcv(msgid,&m,sizeof(m)-sizeof(m.type),m.type,0);//3.接收消息队列中type类型的消息
    printf("the msg len:%d,msg:%s\n",m.len,m.msg);
    msgctl(msgid,IPC_RMID,NULL);
    return 0;
}

运行效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值