zoukankan      html  css  js  c++  java
  • 消息队列函数(msgget、msgctl、msgsnd、msgrcv)及其范例

    消息队列常用命令:

    ipcs -q  

    ipcs -l

    ipcrm -q

    消息队列函数由msgget、msgctl、msgsnd、msgrcv四个函数组成。下面的表格列出了这四个函数的函数原型及其具体说明。

    1.   msgget函数原型

    如果用msgget创建了一个新的消息队列对象时,则msqid_ds结构成员变量的值设置如下:

            msg_qnum、msg_lspid、msg_lrpid、 msg_stime、msg_rtime设置为0。

            msg_ctime设置为当前时间。

            msg_qbytes设成系统的限制值。

            msgflg的读写权限写入msg_perm.mode中。

            msg_perm结构的uid和cuid成员被设置成当前进程的有效用户ID,gid和cuid成员被设置成当前进程的有效组ID。

    2.   msgctl函数原型

    3.   msgsnd函数原型

       msgsnd()为阻塞函数,当消息队列容量满或消息个数满会阻塞。消息队列已被删除,则返回EIDRM错误;被信号中断返回E_INTR错误。

     如果设置IPC_NOWAIT消息队列满或个数满时会返回-1,并且置EAGAIN错误。

    msgsnd()解除阻塞的条件有以下三个条件:

    ①    不满足消息队列满或个数满两个条件,即消息队列中有容纳该消息的空间。

    ②    msqid代表的消息队列被删除。

    ③    调用msgsnd函数的进程被信号中断。

    4.   msgrcv函数原型

    msgrcv()解除阻塞的条件有以下三个:

    ①    消息队列中有了满足条件的消息。

    ②    msqid代表的消息队列被删除。

    ③    调用msgrcv()的进程被信号中断。

    消息队列使用程序范例

    5.   消息队列控制范例
    msgctl.c源代码如下:

    #include <stdio.h>

    #include <string.h>

    #include <unistd.h>

    #include <sys/ipc.h>

    #include <sys/msg.h>

    #include <error.h>

    #define TEXT_SIZE  512

    struct msgbuf

    {

        long mtype ;

        char mtext[TEXT_SIZE] ;

    }  ;

    int main(int argc, char **argv)

    {

        int msqid ;

        struct msqid_ds info ;

        struct msgbuf buf ;

        struct msgbuf buf1 ;

        int flag ;

        int sendlength, recvlength ;

        msqid = msgget( IPC_PRIVATE, 0666 ) ;

        if ( msqid < 0 )

        {

            perror("get ipc_id error") ;

            return -1 ;

        }

        buf.mtype = 1 ;

        strcpy(buf.mtext, "happy new year!") ;

        sendlength = sizeof(struct msgbuf) - sizeof(long) ;

        flag = msgsnd( msqid, &buf, sendlength , 0 ) ;

        if ( flag < 0 )

        {

            perror("send message error") ;

            return -1 ;

        }

        buf.mtype = 3 ;

        strcpy(buf.mtext, "good bye!") ;

        sendlength = sizeof(struct msgbuf) - sizeof(long) ;

        flag = msgsnd( msqid, &buf, sendlength , 0 ) ;

        if ( flag < 0 )

        {

            perror("send message error") ;

            return -1 ;

        }

        flag = msgctl( msqid, IPC_STAT, &info ) ;

        if ( flag < 0 )

        {

            perror("get message status error") ;

            return -1 ;

        }

        printf("uid:%d, gid = %d, cuid = %d, cgid= %d " ,

            info.msg_perm.uid,  info.msg_perm.gid,  info.msg_perm.cuid,  info.msg_perm.cgid  ) ;

        printf("read-write:%03o, cbytes = %lu, qnum = %lu, qbytes= %lu " ,

            info.msg_perm.mode&0777, info.msg_cbytes, info.msg_qnum, info.msg_qbytes ) ;

        system("ipcs -q") ;

        recvlength = sizeof(struct msgbuf) - sizeof(long) ;

        memset(&buf1, 0x00, sizeof(struct msgbuf)) ;

        flag = msgrcv( msqid, &buf1, recvlength ,3,0 ) ;

        if ( flag < 0 )

        {

            perror("recv message error") ;

            return -1 ;

        }

        printf("type=%d, message=%s ", buf1.mtype, buf1.mtext) ;

        flag = msgctl( msqid, IPC_RMID,NULL) ;

        if ( flag < 0 )

        {

            perror("rm message queue error") ;

            return -1 ;

        }

        system("ipcs -q") ;

       return 0 ;

    }

    编译 gcc msgctl.c –o msgctl。

    执行 ./msg,执行结果如下:

    uid:1008, gid = 1003, cuid = 1008, cgid= 1003

    read-write:666, cbytes = 1024, qnum = 2, qbytes= 163840

    ------ Message Queues --------

    key        msqid      owner      perms      used-bytes   messages   

    0x00000000 65536      zjkf       666        1024         2          

    type=3, message=good bye!

    ------ Message Queues --------

    key        msqid      owner      perms      used-bytes   messages  

    6.  两进程通过消息队列收发消息
    (1)发送消息队列程序

    msgsnd.c源代码如下:

    #include <stdio.h>

    #include <string.h>

    #include <unistd.h>

    #include <sys/ipc.h>

    #include <sys/msg.h>

    #include  <time.h>

    #define TEXT_SIZE  512

    struct msgbuf

    {

        long mtype ;

        int  status ;

        char time[20] ;

        char mtext[TEXT_SIZE] ;

    }  ;

    char  *getxtsj()

        time_t  tv ;

        struct  tm   *tmp ;

        static  char  buf[20] ;

        tv = time( 0 ) ;

        tmp = localtime(&tv) ;

        sprintf(buf,"%02d:%02d:%02d",tmp->tm_hour , tmp->tm_min,tmp->tm_sec);

        return   buf ;

    }

    int main(int argc, char **argv)

    {

        int msqid ;

        struct msqid_ds info ;

        struct msgbuf buf ;

        struct msgbuf buf1 ;

        int flag ;

        int sendlength, recvlength ;

        int key ;

        key = ftok("msg.tmp", 0x01 ) ;

        if ( key < 0 )

        {

            perror("ftok key error") ;

            return -1 ;

        }

        msqid = msgget( key, 0600|IPC_CREAT ) ;

        if ( msqid < 0 )

        {

            perror("create message queue error") ;

            return -1 ;

        }

        buf.mtype = 1 ;

        buf.status = 9 ;

        strcpy(buf.time, getxtsj()) ;

        strcpy(buf.mtext, "happy new year!") ;

        sendlength = sizeof(struct msgbuf) - sizeof(long) ;

        flag = msgsnd( msqid, &buf, sendlength , 0 ) ;

        if ( flag < 0 )

        {

            perror("send message error") ;

            return -1 ;

        }

        buf.mtype = 3 ;

        buf.status = 9 ;

        strcpy(buf.time, getxtsj()) ;

        strcpy(buf.mtext, "good bye!") ;

        sendlength = sizeof(struct msgbuf) - sizeof(long) ;

        flag = msgsnd( msqid, &buf, sendlength , 0 ) ;

        if ( flag < 0 )

        {

            perror("send message error") ;

            return -1 ;

        }

        system("ipcs -q") ;

       return 0 ;

    }

    (2)接收消息队列程序

    msgrcv.c源代码如下:

    #include <stdio.h>

    #include <string.h>

    #include <unistd.h>

    #include <sys/ipc.h>

    #include <sys/msg.h>

    #define TEXT_SIZE  512

    struct msgbuf

    {

        long mtype ;

        int  status ;

        char time[20] ;

        char mtext[TEXT_SIZE] ;

    }  ;

    int main(int argc, char **argv)

    {

        int msqid ;

        struct msqid_ds info ;

        struct msgbuf buf1 ;

        int flag ;

        int  recvlength ;

        int key ;

        int mtype ;

        key = ftok("msg.tmp", 0x01 ) ;

        if ( key < 0 )

        {

            perror("ftok key error") ;

            return -1 ;

        }

        msqid = msgget( key, 0 ) ;

        if ( msqid < 0 )

        {

            perror("get ipc_id error") ;

            return -1 ;

        }

        recvlength = sizeof(struct msgbuf) - sizeof(long) ;

        memset(&buf1, 0x00, sizeof(struct msgbuf)) ;

        mtype = 1 ;

        flag = msgrcv( msqid, &buf1, recvlength ,mtype,0 ) ;

        if ( flag < 0 )

        {

            perror("recv message error ") ;

            return -1 ;

        }

        printf("type=%d,time=%s, message=%s ", buf1.mtype, buf1.time,  buf1.mtext) ;

        system("ipcs -q") ;

       return 0 ;

    }

    (3)编译与执行程序

    ①    在当前目录下利用>msg.tmp建立空文件msg.tmp。

    ②    编译发送消息队列程序 gcc msgsnd.c -o  msgsnd。

    ③    执行./msgsnd,执行结果如下:

      ----- Message Queues --------

    key        msqid      owner      perms      used-bytes   messages   

    0x0101436d 294912     zjkf       600        1072         2          

    ④    编译接收消息程序 gcc msgrcv.c -o msgrcv

    ⑤    执行./msgrcv,执行结果如下:

     type=1,time=03:23:16, message=happy new year!

    ------ Message Queues --------

    key        msqid      owner      perms      used-bytes   messages   

    0x0101436d 294912     zjkf       600        536          1         

    ⑥    利用ipcrm -q 294912删除该消息队列。因为消息队列是随内核持续存在的,在程序中若不利用msgctl函数或在命令行用ipcrm命令显式地删除,该消息队列就一直存在于系统中。另外信号量和共享内存也是随内核持续存在的。

    摘录自《深入浅出Linux工具与编程》

  • 相关阅读:
    leetcode Super Ugly Number
    leetcode Find Median from Data Stream
    leetcode Remove Invalid Parentheses
    leetcode Range Sum Query
    leetcode Range Sum Query
    leetcode Minimum Height Trees
    hdu 3836 Equivalent Sets
    hdu 1269 迷宫城堡
    hud 2586 How far away ?
    poj 1330 Nearest Common Ancestors
  • 原文地址:https://www.cnblogs.com/sdushmily/p/10118110.html
Copyright © 2011-2022 走看看