LINUX学习:System V消息队列

介绍:

1.消息队列提供了一个从一个进程向另外一个进程发送数据块的方法

2.每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值

3.消息队列也有管道一样的不足,就是每个消息最大的长度是有上限的(MSGMAX),每个消息队列

的总的字节数是有上限的(MSGMNB),系统上消息队列的总数也是有一个上限的。

 

每个IPC对象都在内核维护着一个数据结构,

消息不同于刘模式,消息是有边界的,消息都是被打包在一个一个的数据包里的。

那么我们看下消息队列结构:

 

 

 

消息队列有4个重要的队列函数:

##创建一个消息队列

int msgget(ket_t key, int msgflg)

key:某个消息队列的名字

msgflg:由九个权限标志构成, 它们的用法和创建文件时使用的mode模式标志是一样的

返回值:成功返回非负整数, 即该消息队列的标识码, 失败返回-1;

 

##i消息队列的控制函数

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

msqid:由msgget函数返回的消息队列标识码

cmd:即将要采取的动作(有三个取值)

返回值:成功返回0,失败返回-1;

 

IPC_STAT:

将消息队列的信息保存到下面结构体:

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

IPC_RMID:

删除该消息队列

3.msgsnd

将一条消息添加到消息队列中

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

msgid:消息队列标识码

msgp:一个指向准备发送的消息的指针;

msgsz:msgp指向的消息的长度,这个长度不含保存消息类型的那个long int长整形;

msgflg:控制着当前队列消息满或者到达系统上线时要法神的事情

返回值:成功返回0,失败返回-1;

 

##msgflg = IPC_NOWAIT表示队列不等待,返回EAGAIN错误。

消息结构在两方面受到制约,首先它必须小于系统规定的上限值;其次,它必须以一个long int长整数

开始, 接收者函数将利用这个长整数确定消息的类型;

 

消息结构参考如下:

struct msgbuf {

    long mtype;       /* message type, must be > 0 */

    char mtext[1];    /* message data */

};

 

下面我们写一个发送函数练习一下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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

#define ERR_EXIT(m)     do {         perror(m);        exit(EXIT_FAILURE);    }while(0)
struct msgbuf{
    long mtype;
    char mtext[1];
};

int main(int argc, const char *argv[])
{
    if(argc != 3)
    {
        fprintf(stderr, "usgage :%s <bytes> <type>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    int len = atoi(argv[1]);
    int type = atoi(argv[2]);
    int msgid;
    //创建一个消息队列
    msgid = msgget(1111, 0);
    if(msgid == -1)
        ERR_EXIT("msgget");

    struct msgbuf *ptr;
    ptr = (struct msgbuf*)malloc(sizeof(long) + len);
    ptr->mtype = type;
    if(msgsnd(msgid, ptr, len, IPC_NOWAIT) <0)
        ERR_EXIT("msgsnd");

    return 0;
}

亲测有效,只需保证msgid = 1111的消息队列存在即可;

 

 

4.msgrcv函数

从一个消息队列接收消息,略微比snd函数复杂;

原型 ssize_t msgrcv(int msgqid, void *msgp,  size_t msgsz, long msgtype, int msgflg);

msgid:消息队列标识码

msgp:一个指向准备发送的消息的指针;

msgsz:msgp指向的消息的长度,这个长度不含保存消息类型的那个long int长整形;

msgtype:他可以实现接收优先级的简单形式

msgflg:控制着当前队列消息中没有相应类型的消息可供接收时将要发送的事;

返回值:成功返回实际放到接收缓冲区里去的字符个数,失败返回-1;

 

msgtype=0 返回队列第一条消息

msgtype>0 返回队列第一条等于msgtype的消息;

msgtype<0返回队列第一类型小于等于msgtype绝对值的消息

msgflg=IPC_NOWAIT ,队里没有可读消息不等待,返回ENOMSG错误

msgflg=MSG_NOERROR,消息大小超过msgsz时被阶段

msgtype》0且msgflg=MSC)EXCEPT,接收第一条

 

这里插空介绍一个函数

getopt 可以实现对函数的 选项设置

int main(int argc, const char *argv[])
{
    int flag = 0;
    int type = 0;
    int opt;
    while(1)
    {
        opt = getopt(argc, argv,"nt:");
        if(opt == ‘?‘)
            exit(EXIT_FAILURE);
        if(opt == -1)
            exit(0);

        switch(opt)
        {
            case ‘n‘:
               // printf("NNNN\n");
                flag |= IPC_NOWAIT;
                break;
            case ‘t‘:
               /* printf("TTTTT\n");
                int n = atoi(optarg);
                printf("(b=%d)\n", n);
                */
                type = atoi(optarg);

                break;
        }
时间: 2024-10-05 05:41:20

LINUX学习:System V消息队列的相关文章

细说linux IPC(十):system V 消息队列

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu,文章仅供学习交流,请勿用于商业用途] system V消息队列和posix消息队列类似,linux系统这两种消息队列都支持.先来看一下system V消息队列相关操作及其函数. msgget()函数创建一个消息队列或打开一个消息队列. #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h&

利用System V消息队列实现回射客户/服务器

一.介绍 在学习UNIX网络编程 卷1时,我们当时可以利用Socket套接字来实现回射客户/服务器程序,但是Socket编程是存在一些不足的,例如: 1. 服务器必须启动之时,客户端才能连上服务端,并与服务端进行通信: 2. 利用套接口描述符进行通信,必须知道对端的IP与端口. 二.相关函数介绍 下面,我们利用System V消息队列来实现进程间的通信: 首先,我们先来了解一下下面几个函数: 1. msgget: 该函数用于打开或创建消息队列,其作用相当与文件操作函数open. #include

进程间通信 System V 消息队列

1.msgget (key_t ket,int flag) ; //创建一个新的消息队列或者访问一个已存在的消息队列 2.msgsnd(int msid, const void *ptr ,size_t length ,int flag ) // 发送 3.msgrcv() //读 4.msgctl(int msid , int cmd ,struct  msqid_ds *buff )//  cmd 提供删除,设置,返回当前 tips : 1.客户端服务端例子 服务端创建两个消息队列,A,B,

System V消息队列(2)

msgsnd函数 功能:把一条消息添加到消息队列中 原型 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 参数 msgid: 由msgget函数返回的消息队列标识码 msgp:是一个指针,指针指向准备发送的消息, msgsz:是msgp指向的消息长度,这个长度不含保存消息类型的那个long int长整型 msgflg:控制着当前消息队列满或到达系统上限时将要发生的事情 返回值:成功返回0:失败返回-1 msgs

Linux进程间通信——使用System V 消息队列

消息队列 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法. 每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构.我们可以通过发送消息来避免命名管道的同步和阻塞问题.但是消息队列与命名管道一样,每个数据块都有一个最大长度的限制. Linux用宏MSGMAX和MSGMNB来限制一条消息的最大长度和一个队列的最大长度. 在Linux中使用消息队列 Linux提供了一系列消息队列的函数接口来让我们方便地使用它来实现进程间的通信. msgget 函数 创建和访问一个

Linux IPC实践(6) --System V消息队列(3)

消息队列综合案例 消息队列实现回射客户/服务器 server进程接收时, 指定msgtyp为0, 从队首不断接收消息 server进程发送时, 将mtype指定为接收到的client进程的pid client进程发送的时候, mtype指定为自己进程的pid client进程接收时, 需要将msgtyp指定为自己进程的pid, 只接收消息类型为自己pid的消息; // client/server进程接收/发送的数据结构 const int MSGMAX = 8192; struct msgBuf

Linux IPC实践(5) --System V消息队列(2)

消息发送/接收API msgsnd函数 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 参数 msgid: 由msgget函数返回的消息队列标识码, 也可以是通过ipcs命令查询出来的一个已经存在的消息队列的ID号 msgp:是一个指针,指针指向准备发送的消息, msgsz:是msgp指向的消息长度, 注意:这个长度不含保存消息类型的那个long int长整型 msgflg:控制着当前消息队列满或到达系统上限时

Linux IPC实践(4) --System V消息队列(1)

消息队列概述 消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法(仅局限于本机); 每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值. 消息队列也有管道一样的不足: (1)每个消息的最长字节数的上限(MSGMAX); (2)系统中消息队列的总条数也有一个上限(MSGMNI); (3)每个消息队列所能够保存的总字节数是有上限的(MSGMNB) . 查看系统限制 cat /proc/sys/kernel/msgmax  #最大消息长度限制 cat /proc/sys

System V 消息队列

3.1 概述 消息队列结构: struct msqid_ds { struct ipc_perm msg_perm; //权限结构 struct msg *msg_first; //队列中第一个消息 struct msg *msg_last; //队列中最后一个消息 msglen_t msg_cbytes; //队列中当前消息总字节数 msglen_t msg_qbytes; //队列中最大消息总字节数 msgqnum_t msg_qnum; //队列中当前消息数 pid_t msg_lspid