Linux学习笔记之---消息队列

9:消息队列
    9.1     ipc结构
            struct ipc_perm
            {
                uid_t  uid;
                gid_t  gid;
                uid_t  cuid;
                gid_t  cgid;
                mode_t mode;
                unsigned short seq;
                key_t key;
            }  
            
    9.2     消息队列结构
            struct msqid_ds
            {
                struct ipc_perm msg_perm;      消息队列的访问权限
                struct msg * msg_first;        第一个消息的指针
                struct msg * msg_last;         最后一个消息的指针
                msgqnum_t msg_qnum;            队列当前的消息个数
                unsigned short msg_cbytes;     队列的消息字节数
                msglen_t msg_qbytes;           队列可容纳的字节数
                pid_t msg_lspid;               最后发送消息的进程号
                pid_t msg_lrpid;               最后接收消息的进程号
                time_t msg_stime;              最后发送消息的时间
                time_t msg_rtime;              最后接收消息的时间
                time_t msg_ctime;              最近修改消息队列的时间
            };
            msg 结构体的定义
            struct msg
            {
                struct msg * msg_next;         指向队列中的下一条消息
                long         msg_type;         本条消息的类型
                short        msg_ts;           本条消息的长度
                short        msg_sport;        本条消息的数据地址
            }
            
    9.3     消息结构
            struct msgbuf
            {
                long mtype;         消息类型
                char mtext[1];      消息数据(此处只是用char来举例)
            }                   
            
    9.4     消息队列的创建
            #include <sys/types.h>
            #include <sys/ipc.h>
            #include <sys/msg.h>
            int msgget (key_t key, int msgflg);
            msgfla低9位指定访问权限,高9位指定消息队列的创建方式:
            IPC_CREAT       创建消息队列,若果存在就打开消息队列
            IPC_EXCL        与IPC_CREAT同用,创建一个不存在的消息队列
            调用成功返回消息队列的标识符,否则-1.
            例1:创建关键字为0x1234,访问权限为0666的消息队列
            如果存在返回标识号
            int msgid;
            msgid = msgget(0x1234, 0666|IPC_CREAT);
            例2:创建关键字为0x1234,访问权限为0666的消息队列
            如果存在则报错
            int msgid;
            msgid = msgget(0x1234, 0666|IPC_CREAT|IPC_EXCL);
                    
    9.5     消息队列放送
            #include <sys/types.h>
            #include <sys/ipc.h>
            #include <sys/msg.h>
            int msgsnd(int msgid,void *msgp,int msgsz,int msgflg);
            msgsnd向消息队列msgid发送一条消息:
            msgid指定了发送消息队列的标识号
            msgp指向存储待发送消息内容的地址,
            msgsz指定消息数据的长度(不包含消息类型的长度)                
            msgflg控制消息发送的方式,如果设置了IPC_NOWAIT采用非阻塞
            
    9.6     消息队列发送模型 
            以阻塞方式向消息队列(关键字)为KEY中写入字符串"Hello UNIX!"
            消息类型为TYPE:
            1.定义消息结构
            struct msgbuf
            {
                long mtype
                char ctext[100];
            };
            2.打开(创建)消息队列
            int msgid;
            msgid = msgget(KEY, 0666|IPC_CREAT);
            if(msgid < 0) 打开(创建消息)失败
            3.组装消息
            设置消息类型和拷贝消息数据
            struct msgbuf buf;
            buf.mtype = 100;
            strcpy(buf.ctext, "Hello UNIX!");
            4.发送消息
            int ret;
            ret = msgsnd(msgid, &buf, strlen(buf.ctext),0); 
            5.发送判断
            if (ret == -1)
            {
               if(errno == EINTR)
                   信号中断,重新发送
               else 系统错误
            }
            
    9.7     消息队列接收函数
            #include <sys/types.h>
            #include <sys/ipc.h>
            #include <sys/msg.h>
            int msgrcv(int msgid,void *msgp,int msgsz,long msgtyp,int msgflg);
            msgrcv从消息队列msgid中读取一条消息:
            msgid指定了接收消息队列的标识号
            msgp指向存接收消息内容的地址,
            msgsz指定该缓冲区的最大容量(包含消息类型的长度)  
            msgtyp指定读取消息的类型:
                0        读取队列中的第一个消息
                正整数   读取队列中第一个类型为msgtyp的消息
                负整数   读取队列中第一个类型小于或等于msgtyp的绝对值的消息          
            msgflg控制消息接收的方式:
                IPC_NOWAIT          非阻塞方式读取消息
                MSG_NOERROR         截断读取消息
            调用成功返回接收到的字节数否则-1,并根据以下情况设置errno的值:
            1.消息放送中队列被系统删除,返回-1,errno = EIDRM
            2.如果msgflg设置了IPC_NOWAIT,当队列没有该消息时返回-1,errno=EAGAIN
            3.如果msgflg没有设置IPC_NOWAIT当队列没有该消息时,一直等待
            
    9.8     消息队列接收模型
            以阻塞方式从消息队列(关键字为KEY)中接收一条消息
            消息类型为TYPE:
            1.定义消息结构
            与发送消息中的结构相一致
            2.打开(创建)消息队列
            int msgid;
            msgid = msgget(KEY, 0666|IPC_CREAT);
            3.准备接收缓冲区
            struct msgbuf buf;
            memset(buf,0,sizeof(buf));
            4.接收消息
            int ret;
            ret = msgrcv(msgid, &msg, sizeof(msg.ctext),TYPE,0);
            5.接收判断
            if (ret == -1)
            {
                if (errno == EINTR)
                    信号中断,重新接收
                else  系统错误
            }
            
    9.9     消息队列的控制
            #include <sys/types.h>
            #include <sys/ipc.h>
            #include <sys/msg.h>
            int msgctl(int msgid,int cmd,struct msgid_ds *buf);
            cmd取值:
            IPC_CMID: 删除消息队列msqid
            IPC_STAT: 读取消息队列数据结构到buf
            IPC_SET:  设置消息队列结构msgid_ds的成员
            调用成功返回0,否则-1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值