• Linux IPC 消息队列


     管道和FIFO是字节流,没有消息边界。

    1. Posix 消息队列

    /* mq_open - open a message queue */
    #include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For mode constants */ #include <mqueue.h> mqd_t mq_open(const char *name, int oflag); mqd_t mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr);
    /*  mq_send, mq_timedsend - send a message to a message queue */ #include
    <mqueue.h> int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio); #include <time.h> #include <mqueue.h> int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio, const struct timespec *abs_timeout);
    /* mq_receive, mq_timedreceive - receive a message from a message queue */ #include
    <mqueue.h> ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio); #include <time.h> #include <mqueue.h> ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abs_timeout);
    /* mq_getattr, mq_setattr - get/set message queue attributes */
    #include <mqueue.h>
    int mq_getattr(mqd_t mqdes, struct mq_attr *attr); int mq_setattr(mqd_t mqdes, struct mq_attr *newattr, struct mq_attr *oldattr); struct mq_attr { long mq_flags; /* Flags: 0 or O_NONBLOCK */ long mq_maxmsg; /* Max. # of messages on queue */ long mq_msgsize; /* Max. message size (bytes) */ long mq_curmsgs; /* # of messages currently in queue */ };
    /* mq_notify - register for notification when a message is available */
    int mq_notify(mqd_t mqdes, const struct sigevent *sevp);

    /* mq_unlink - remove a message queue */
    int mq_unlink(const char *name); Link with
    -lrt.

    Posix消息队列注意事项

    1. mq_setattr只能修改mq_flags为阻塞或非阻塞,其他的参数只能通过mq_open在建立消息队列时指定

    2. mq_receive每次都返回队列中最高优先级的最早消息

    3. mq_notify支持注册一个信号或者线程,在一个消息被加入到一个空队列时发送信息或者激活线程(System V消息队列不提供类似的形式)

    2. System V 消息队列

    /* msgget - get a System V message queue identifier */
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    
    int msgget(key_t key, int msgflg);
    
    /* ftok - convert a pathname and a project identifier to a System V IPC key */
    #include <sys/types.h>
    #include <sys/ipc.h>
    
    key_t ftok(const char *pathname, int proj_id);
    
    /* msgrcv, msgsnd - System V message queue operations */
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    
    int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
    
    ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
    
    /* msgctl - System V message control operations */
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    
    int msgctl(int msqid, int cmd, struct msqid_ds *buf);
    
    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) */
    };

    System V消息队列注意事项

    1. msgsnd的flag参数可以指定为IPC_NOWAIT。IPC_NOWAIT标志使得此次msgsnd操作为非阻塞:如果没有新消息的存放空间,函数立即返回一个EAGIN错误,出现这种情况的情形如下:

    a. 在该消息队列中已经有太多的字节(对应struct msqid_ds中的msg_qbytes)

    b. 在系统范围内存在太多的消息

    如果出现上述两个条件之一,且msgsnd未指定IPC_NOWAIT标志,那么调用线程被投入睡眠,直到:

    a. 具备存放新消息的空间

    b. 指定的消息队列被消除了(这种情况下msgsnd返回ERMID错误)

    c. 调用线程被某个捕获的信号中断(这种情况msgsnd返回EINTR错误)

     

    2. msgrcv的flag参数也可以指定为IPC_NOWAIT,还有另一个标志 MSG_NOERROR:当所接收的消息数据部分大于msgrcv的length参数,如果设置了MSG_NOERROR,数据被截断,msgrcv函数不会出错;如果没有设置该标志,msgrcv函数返回E2BIG错误。

     

    3. msgctl的cmd可以取值如下:

    IPC_RMID: 删除指定队列

    IPC_SET: 支持设置指定队列的 msgid_ds结构体中的 msg_prem.uid, msg_prem.gid, msg_prem.mode 和 msg_qbytes

    IPC_STAT: 返回指定队列的msgid_ds 结构

     

    4. system V 消息队列的限制

    可以查看proc/sys/kernel/文件夹下的msgmax  msgmni  msgmnb

    也可以通过ipcs  -l 命令查看:

    ubuntu: ipcs -l
    
    ------ Shared Memory Limits --------
    max number of segments = 4096
    max seg size (kbytes) = 32768
    max total shared memory (kbytes) = 8388608
    min seg size (bytes) = 1
    
    ------ Semaphore Limits --------
    max number of arrays = 128
    max semaphores per array = 250
    max semaphores system wide = 32000
    max ops per semop call = 32
    semaphore max value = 32767
    
    ------ Messages Limits --------
    max queues system wide = 1717                 系统范围内的消息队列最大数量:msgmni
    max size of message (bytes) = 8192            每个消息的最大字节数:msgmax
    default max size of queue (bytes) = 16384   每个消息队列上的最大字节数:msgmnb
  • 相关阅读:
    Educational Codeforces Round 85 D. Minimum Euler Cycle(模拟/数学/图)
    Educational Codeforces Round 85 C. Circle of Monsters(贪心)
    NOIP 2017 提高组 DAY1 T1小凯的疑惑(二元一次不定方程)
    Educational Codeforces Round 85 B. Middle Class(排序/贪心/水题)
    Educational Codeforces Round 85 A. Level Statistics(水题)
    IOS中的三大事件
    用Quartz 2D画小黄人
    strong、weak、copy、assign 在命名属性时候怎么用
    用代码生成UINavigationController 与UITabBarController相结合的简单QQ框架(部分)
    Attempting to badge the application icon but haven't received permission from the user to badge the application错误解决办法
  • 原文地址:https://www.cnblogs.com/xiaokuang/p/4613363.html
Copyright © 2020-2023  润新知