Linux 进程间通信(七)消息队列

版权声明:转载请声明 https://blog.csdn.net/qq_40732350/article/details/82844100

顾名思义, 消息队列就是一些消息的列表, 用户可以在消息队列中添加消息和读取消息等。从这点上看, 消息队列具有一定的 FIFO 特性, 但是它可以实现消息的随机查询, 比 FIFO具有更大的优势。 同时, 这些消息又是存在于内核中的, 由“队列 ID” 来标识。

消息队列的实现包括创建或打开消息队列、 添加消息、 读取消息和控制消息队列 4 种操作,

创建或打开消息队列使用的函数是 msgget(), 这里创建的消息队列的数量会受到系统消息队列数量的限制;

添加消息使用的函数是 msgsnd(), 它把消息添加到已打开的消息队列末尾;

读取消息使用的函数是 msgrcv(), 它把消息从消息队列中取走, 与 FIFO 不同的是,这里可以取走指定的某一条消息;

控制消息队列使用的函数是 msgctl(), 它可以完成多项功能。
 

msgget()函数的语法要点。
函数原型

int msgget(key_t key, int msgflg)
函数传入值
key: 消息队列的键值, 多个进程可以通过它访问同一个消息队列, 其中有个特殊值IPC_PRIVATE, 用于创建当前进程的私有消息队列
msgflg: 权限标志位
函数返回值
成功: 消息队列 ID
出错: 1

msgsnd()函数的语法要点。

函数原型

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)
函数传入值
msqid: 消息队列的队列 ID
msgp: 指向消息结构的指针, 该消息结构 msgbuf 通常如下。

扫描二维码关注公众号,回复: 3429024 查看本文章
  • struct msgbuf
  •     long mtype; /* 消息类型, 该结构必须从这个域开始 */
  •     char mtext[1]; /* 消息正文 */

msgsz: 消息正文的字节数(不包括消息类型指针变量)
msgflg:

  1. IPC_NOWAIT: 若消息无法立即发送(如当前消息队列已满) , 函数会立即返回
  2. 0: msgsnd 调用阻塞直到发送成功为止

函数返回值
成功: 0
出错: 1

msgrcv()函数的语法要点。

函数原型

int msgrcv(int msgid, void *msgp, size_t msgsz, long int msgtyp, int msgflg)
函数传入值

msqid: 消息队列的队列 ID
msgp: 消息缓冲区, 同 msgsnd()函数的 msgp
msgsz: 消息正文的字节数(不包括消息类型指针变量)
msgtyp:

  1. 0: 接收消息队列中第一个消息
  2. 大于 0: 接收消息队列中第一个类型为 msgtyp 的消息续表
  3. 小于 0: 接收消息队列中第一个类型值不小于 msgtyp 绝对值且类型值最小的消息

msgflg:

  1. MSG_NOERROR:若返回的消息比 msgsz 字节多,则消息就会截短到 msgsz字节, 且不通知消息发送进程
  2. IPC_NOWAIT: 若在消息队列中并没有相应类型的消息可以接收, 则函数立即返回
  3. 0: msgsnd()调用阻塞直到接收一条相应类型的消息为止

函数返回值
成功: 0
出错: 1
 

重要结构体:

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 (nonstandard) */
               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) */
           };

//The ipc_perm structure is defined as follows (the highlighted fields are settable using IPC_SET):

struct ipc_perm {
               key_t          __key;       /* Key supplied to msgget(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 */
           };

猜你喜欢

转载自blog.csdn.net/qq_40732350/article/details/82844100