linux消息队列

创建
创建一个新的或打开一个已经存在的消息队列

int msgget(key_t key, int msgflg);

key:消息队列关联的键
msgflg:
IPC_CREAT如果内核中没有此队列,则创建
IPC_EXCL和IPC_CREAT一起使用时,如果队列已经存在,则创建失败
返回值:消息队列标识值

写入/读取
写入、读取消息队列

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);

struct msgbuf
{
    long mtype;       /* message type, must be > 0 */
    char mtext[1];    /* message data */
};

msgp:指向msgbuf的指针
msgtyp:消息类型
msgtyp等于0,返回队列的最早的一个消息
msgtyp大于0,返回其类型为mtype的第一个消息
msgtyp小于0,返回其类型小于或等于mtype参数的绝对值的最小的一个消息
msgflg:
IPC_NOWAIT,如果消息队列为空,则返回ENOMSG;如果不指定这个参数,那么进程将被阻塞直到函数可以从队列中得到符合条件的消息为止
MSG_EXCEPT,返回队列中第一个类型不为msgtyp的消息
MSG_NOERROR,如果函数取得的消息长度大于msgsz,将只返回msgsz 长度的信息,剩下的部分被丢弃了;如果不指定这个参数,E2BIG 将被返回,而消息则留在队列中不被取出

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

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

cmd:
IPC_STAT,读取消息队列的数据结构msqid_ds
IPC_SET,设置消息队列的数据结构msqid_ds
IPC_RMID,从系统内核中移除消息队列

举例

struct msgbuf
{
    long mtype;       /* message type, must be > 0 */
    char mtext[1024]; /* message data */
};

int msqid = msgget((key_t)123, IPC_CREAT);
if(msqid < 0)
{
    perror("msgget.");
    return msqid;
}

struct msgbuf sbuf = {0};
sbuf.mtype = 1; //设置类型
char *text = "hello furong."; //填写数据
memcpy(sbuf.mtext, text, strlen(text));

if(fork() == 0)
{
    while(1)
    {
        if(msgsnd(msqid, &sbuf, sizeof(struct msgbuf), IPC_NOWAIT) < 0)
        {
            perror("msgsnd.");
        }
        sleep(1);
    }
}   

struct msgbuf rbuf = {0};
while(1)
{   
    memset(&rbuf, 0, sizeof(rbuf));
    if(msgrcv(msqid, &rbuf, sizeof(struct msgbuf), 0, 0) < 0)
    {
        perror("msgrcv.");
        sleep(1);
    }
    puts(rbuf.mtext);
}

msgctl(msqid, IPC_RMID, 0);

命令

# ipcs -q //消息队列
posted @ 2017-05-15 12:54  thomas_blog  阅读(93)  评论(0编辑  收藏  举报