个人整理的消息队列的几个函数

来源:互联网 发布:淘宝村服务站怎样申请 编辑:程序博客网 时间:2024/04/29 15:08


   struct msqid_ds
    {
      struct ipc_perm msg_perm;     //structure describing operation permission
      time_t msg_stime;             //发送到队列的最后一个消息的时间戳
      time_t msg_rtime;             //最后一次接收数据时间
      time_t msg_ctime;             //对队列进行最后一次变动的时间戳
      unsigned long int __msg_cbytes; // 当前队列驻留的字节数
      msgqnum_t msg_qnum;             //当前处于队列的消息数
      msglen_t msg_qbytes;             //队列中所能容纳的字节的最大数目
      pid_t msg_lspid;                 //发送最后一个消息进程的PID
      pid_t msg_lrpid;                 //最后一次接受消息进程的PID
    };
   
    struct ipc_perm {
       key_t       key;          //函数msgget()使用的键值
       uid_t      uid;        // owner’s effective user id
       gid_t      gui;        // owner’s effective group id
       uid_t      cuid;       //creator’s effective user id
       gid_t      cgid;       // creator’s effective group id
       mode_t   mode;           // access mode
       …..
    };


1.  主要函数的介绍(#include <sys/ipc.h>

   1) int msgget(key_t key, int flag); 

     参数:        key: 消息队列的key值,通过ftok获得。

                  flag: 标志位

   返回:    成功返回消息队列描述字,否则返回-1。
     注:该函数初始化结构msqid_ds成员:  

        * ipc_perm中的mode成员按flag进行设置.
            * msg_qnum, msg_lspid, msg_lrpid, msg_stime和msg_rtime都设置为0.
            * msg_ctime设置为当前时间.
            * msg_qbytes设置为系统限制值.
  参数key设置成常数IPC_PRIVATE并不意味着其他进程不能访问该消息队列,只意味着即将创建新的消息队列。

 

   2)    int msgctl(int msqid, int cmd, struct msgqid_ds *buf);   

   参数:     cmd参数说明对msqid指定的队列要执行的命令
               IPC_STAT: 取此队列的msqid_ds结构, 并将它存放在buf指向的结构中.

               IPC_SET: 按由buf指向结构中的值, 设置与此队列相关结构中的msg_perm.uid, msg_perm.gid,   msg_perm.mode和msg_qbytes. 该命令只有下列两种进程可以执行:

                        o 有效用户ID等于msg_perm.cuid或msg_per.uid.
                        o 具有超级用户特权的进程.
          IPC_RMID: 从系统中删除该消息队列以及仍在该队列中的所有数据. 执行权限同上.

   返回: 成功返回0,否则返回-1。


  3 )    int msgsnd(int msqid, const void *msg_ptr, size_t msg_sz, int msgflg)

  参数:     msgid,是由msgget函数所返回的消息队列标识符
          msg_ptr,是一个指向要发送消息的指针,正如前面所描述的,这个消息必须以long int类型开始。
            msg_sz,是由msg_ptr所指向的消息的尺寸。这个尺寸必须不包含long int消息类型
            msgflg,控制如果当前消息队列已满或是达到了队列消息的系统限制时如何处理
                    如果msgflg标记设置了IPC_NOWAIT,函数就会立即返回而不发送消息,并且返回值为-1。
                    如果msgflg标记清除了IPC_NOWAIT标记,发送进程就会被挂起,等待队列中有可用的空间
      返回:   如果成功,函数会返回0,如果失败,则会返回-1。如果调用成功,系统就会复制一份消息数据并将其放入消息队列中。


  4 )    int msgrcv(int msqid, void *msg_ptr, size_t msg_sz, long int msgtype, int msgflg);

  参数:  msqid,是由msgget函数所返回的消息队列标记符
           msg_ptr,是一个指向将要接收消息的指针,这个消息必须以long int类型开始。
           msg_sz,是由msg_ptr所指向的消息的尺寸,并不包含long int消息类型
           msgtype,是一个long int类型,允许一个接收优先级形式的实现。

         如果msgtype的值为0,队列中第一个可用的消息就会被接收。
                    如果其值大于0,具有相同消息类型的第一个消息就会被接收。

         如果其值小于0,第一个具有相同类型或是小于msgtype绝对值的消息就会被接收。
                    (注:如果我们只是简单的希望以其发送的顺序来接收消息,我们可以将msgtype设置为0。
                       如果我们希望接收特殊消息类型的消息,我们可以将msgtype设置为等于这个值。
                       如果我们希望接收消息类型为n或是小于n的值,我们可以将msgtype设置为-n。)
         msgflg,控制当没有合适类型的消息正在等待被接收时如何处理。如果在msgflg中设置了IPC_NOWAIT位,调用就会立即返回,而返回值为-1。
                如果msgflg标记中消除了IPC_NOWAIT位,进程就会被挂起,等待一个合适类型的消息到来。
      返回:         如果成功,msgrcv会返回放入接收缓冲区中的字节数,消息会被拷贝到由msg_ptr所指向的用户分配缓冲区中,而数据就会由消息队列中删除。如果失败则会返回-1。


    * linux对消息队列的限制
    #define MSGMNI 16    //系统中最大的消息队列数
    #define MSGMAX 8192 //可发送最长的消息字节数
    #define MSGMNB 16384 //一个特定队列中最大的字节数(队列中所有消息之和)