【Linux】Linux进程间通信之消息队列

1、消息队列概念引入

   消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值消息队列也有管道一样的不足,就是每个消息的最大长度是有上限的(MSGMAX),每个消息队列的总的字节数是有上限的(MSGMNB),系统上消息队列的总数也有一个上限(MSGMNI)

2、进程间通信数据结构

内核为每个进程间通信对象维护了一个数据结构

struct ipc_perm {
key_t __key; /* Key supplied to xxxget(2) */
uid_t uid; /* Effective UID of owner */
gid_t gid; /* Effective GID of owner */
uid_t cuid; /* Effective UID of creator */
gid_t cgid; /* Effective GID of creator */
unsigned short mode; /* Permissions */
unsigned short __seq; /* Sequence number */
};

消息队列在内核中的表示:

struct msqid_ds {
struct ipc_perm msg_perm;
struct msg *msg_first; /* first message on queue,unused */
struct msg *msg_last; /* last message in queue,unused */
__kernel_time_t msg_stime; /* last msgsnd time */
__kernel_time_t msg_rtime; /* last msgrcv time */
__kernel_time_t msg_ctime; /* last change time */
unsigned long msg_lcbytes; /* Reuse junk fields for 32 bit */
unsigned long msg_lqbytes; /* ditto */
unsigned short msg_cbytes; /* current number of bytes on queue */
unsigned short msg_qnum; /* number of messages in queue */
unsigned short msg_qbytes; /* max number of bytes on queue */
__kernel_ipc_pid_t msg_lspid; /* pid of last msgsnd */
__kernel_ipc_pid_t msg_lrpid; /* last receive pid */
};

3、消息队列相关的函数

(1)msgget函数

函数原型:

#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/msg.h>

int msgget(key_t key, int msgflag);

功能:

创建和访问一个消息队列。

参数:

参数一表示某个消息队列的名字

参数二表示权限设置为,一共有九个选项可供选择。

返回值:

成功返回一个非负整数,即消息队列的标号,失败返回-1

(2)msgctl函数

函数原型:

#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/msg.h>

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

功能·:

消息队列的控制函数

参数:

参数一表示消息队列标识码

参数二表示将要采取的动作可以有三个选择,

IPC_STAT   IPC_SET   IPC_RMID  IPC_INFO

参数三是一个结构体,

struct msqid_ds {
               struct ipc_perm msg_perm;     /* Ownership and permissions */
               time_t          msg_stime;    /* Time of last msgsnd(2) */
               time_t          msg_rtime;    /* Time of last msgrcv(2) */
               time_t          msg_ctime;    /* Time of last change */
               unsigned long   __msg_cbytes; /* Current number of bytes in
                                                queue (non-standard) */
               msgqnum_t       msg_qnum;     /* Current number of messages
                                                in queue */
               msglen_t        msg_qbytes;   /* Maximum number of bytes
                                                allowed in queue */
               pid_t           msg_lspid;    /* PID of last msgsnd(2) */
               pid_t           msg_lrpid;    /* PID of last msgrcv(2) */

           };

返回值:

成功返回0,失败返回-1

(3)msgsnd函数

函数原型:

 #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>

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

功能:

把一条消息加到消息队列中

参数解释:

参数一:有msgget函数返回的消息队列标识码。

参数二:指针指向要发送的消息

参数三:消息长度

参数四:控制队列满时要发生的事情,msgflg = IPC_NOWAIT,当队列满时不等待,返回EAGAIN错误

返回值:

成功返回0,失败返回-1

说明:

1.消息结构在两方面受到制约:
    首先,它必须小于系统规定的上限值;
    其次,它必须以一个long int长整数开始,接收者函数将利用这个长整数确定消息的类型
2.消息结构参考形式如下:
    struct msgbuf {
        long  mtype;
        char mtext[1];

    };

(4)msgrcv函数

函数原型:

 

 #include <sys/types.h>

  #include <sys/ipc.h>

  #include <sys/msg.h>

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

功能·:

从一个消息队列接收消息

参数解释:

参数一:由magget函数返回的消息队列的标号

参数二:指针,指向准备接收的消息

参数三:消息的长度

参数四:可以实现接收优先级的简单形式,

参数五:控制着队列中没有相应类型的消息可供做的事情

返回值:

成功返回实际放入缓冲区的字符个数,失败返回-1

说明:

msgtype=0返回队列第一条信息
msgtype>0返回队列第一条类型等于msgtype的消息 
msgtype<0返回队列第一条类型小于等于msgtype绝对值的消息,并且是满足条件的消息类型最小的消息
msgflg=IPC_NOWAIT,队列没有可读消息不等待,返回ENOMSG错误。
msgflg=MSG_NOERROR,消息大小超过msgsz时被截断
msgtype>0且msgflg=MSG_EXCEPT,接收类型不等于msgtype的第一条消息。

实现代码:

server.c

client.c

comm.h

comm.c

运行结果:

这样就可以实现进程间不断的对话一样的数据交流。

使用ipcs  -q命令可以看当前的所有消息队列,使用ipcrm -q msqid

删除消息队列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值