LInux 之消息队列

消息队列操作流程大概可以分为以下几个步骤:
1、使用ftok()函数创建消息队列的key值:

//from /usr/include/sys/ipc.h
key_t ftok(const char* path,int id);

第1个参数为任意一个文件名,第2个参数为任意id值。

2、使用函数msgget()创建消息队列ID值:

//from /usr/include/sys/msg.h
int msgget(key_t key,int msgflag);

函数第1个参数为ftok()返回的键值,第2个参数为该消息队列的权限,且msgflag的高位包含以下属性项:

//from /usr/include/bit/ipc.h
#define  IPC_CREAT  00001000  //如果key值不存在则创建
#define  IPC_EXCL   00002000  //如果key存在,则返回失败
#define  IPC_NOWAIT 00004000  //如果需要等待时,直接返回错误

3、使用msgctl()函数设置或获取消息队列属性:

//from /usr/include/sys/msg.h
int msgctl(int msgid,int cmd,struct msqid_ds* buf);

函数第1个参数为msgget()返回的消息队列标识符,第2个参数cmd为执行的控制操作,包括以下选项:

//from /usr/include/linux/ipc.h
#define  IPC_RMID  0    // 立即删除消息队列
#define  IPC_SET   1    // 设置buf中的消息队列属性
#define  IPC_STAT  2    // 获取消息队列的属性并保存在buf中
#define  IPC_INFO  3    // 获取限制信息

4、使用msgsnd()函数发送消息:

//from /usr/include/sys/msg.h
int msgsnd(int msgid,void* msg,size_t size,int msgflag);

函数第1个参数为消息队列标识符,第2个参数为用户定义的缓冲区,使用以下结构:

//from /usr/include/sys/msg.h
struct msgbuf
{
    long mtype;         //消息类型
    char mtext[1];      //消息内容,可重新定义
};

第3个参数为接收消息的大小,第4个参数指定消息达到系统界限时,要采取的操作,一般取IPC_NOWAIT即如果需要等待,则函数立即返回错误。若设置为0,则表示函数将会一直阻塞。

5、使用msgrcv()函数接收消息:

//from /usr/include/sys/msg.h
int msgrcv(int msgid,void* msg,size_t size,,long mtype,int msgflag);

函数参数同msgsnd()一样,只是多了一个mtype,表示要接收的消息队列类型。

以下是消息队列测试代码,起动两个进程,一个不断从终端读取数据并发送出去,另一个进程不断读取消息队列内容,并打印出来,方式均为非阻塞

msg_send.c

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h> 
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/ipc.h>
#include <sys/msg.h>


typedef struct msg
{
    int mtype;
    char mtext[1024];

}MSG;

int main()
{
    MSG msg;
    key_t key;
    int msgid = 0;
    char sendbuf[1024];
    struct msqid_ds buf;

    memset(&buf,0,sizeof(struct msqid_ds));
    memset(sendbuf,0,sizeof(sendbuf));
    memset(&msg,0,sizeof(msg));

    key = ftok("/tmp",'a');
    msgid = msgget(key,0755|IPC_CREAT);

    while(1)
    {
        memset(&msg,0,sizeof(MSG));
        gets(msg.mtext);
        msg.mtype = 10;

        if(msgsnd(msgid,&msg,sizeof(msg),0))
        {
            printf("msgsnd fail\n");
            exit(1);
        }
    }
    return 0;
}

msg_recv.c

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h> 
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/ipc.h>
#include <sys/msg.h>
typedef struct msg
{
    int mtype;
    char mtext[1024];

}MSG;

int main()
{
    MSG msg;
    key_t key;
    int msgid = 0;
    char sendbuf[1024];
    struct msqid_ds buf;

    memset(&buf,0,sizeof(struct msqid_ds));
    memset(sendbuf,0,sizeof(sendbuf));

    key = ftok("/tmp",'a');
    msgid = msgget(key,0755|IPC_CREAT);

    while(1)
    {
        memset(&msg,0,sizeof(msg));
        msgrcv(msgid,&msg,sizeof(msg),11,0);
        printf("mtype=%d,msgrcv = %s\n",msg.mtype,msg.mtext);
    }
    return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chiang木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值