消息队列

  1. 消息队列的使用方法:
    发送者:
    (1)获取消息队列的ID
    (2)将数据放入一个附带有标识的特殊的结构体,发送给消息队列
    接收者:
    (1)获取消息队列的ID
    (2)将指定标识的消息读出
    当发送者和接收者都不再使用消息队列时,及时删除它以释放系统资源
  2. 获取消息队列的ID
     #include<sys/types.h>
     #include<sys/ipc.h>
     #include<sys/msg.h>
     int msgget(ket_t key,int msgflg);
    

    key是消息队列的键值,msgflg有三种取值:IPC_CREATE,当key对应的MSG不存在时则创建该对象,IPC_EXCL,如果该key对应的MSG已经存在,则报错,mode则是MSG的访问权限(八进制,如0644),如果执行成功则返回该消息队列的ID,失败则为-1

  3. 选项msgflg是一个位屏蔽字,因此IPC_CREATEIPC_EXCLmode可以用位或的方式叠加起来,比如:msgget(key,IPC_CREATE|0666);表示如果key对应的消息队列不存在就创建,且权限指定为0666,若已存在就直接获取ID
  4. mode权限只有读和写,执行权限是无效的,例如0777和0666是等价的,当key被指定为IPC_PRIVATE时,系统会自动产生一个未用的key来对应一个新的消息队列对象,一般用于线程间通信
  5. 发送与接收消息
     #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);
    

    msqid代表发送、接收消息的消息队列ID,msgp表示要发送的数据、要接收数据的存储区指针,msgsz代表要发送的数据、接收数据的大小,msgtyp这是msgrcv独有的参数,代表要接收的消息的标识,msgflg有三种取值:IPC_NOWAIT表示非阻塞读出、写入消息,MSG_EXCEPT表示读取标识不等于msgtyp的第一个消息,MSG_NOERROR表示消息尺寸比msgsz大时,截断消息而不报错,msgsnd成功返回0,msgrcv成功返回真正读取的字节数,失败二者都会返回-1

  6. 发送消息时,消息必须被组织成以下形式:
     struct msgbuf{
         long mtype;//消息标识
         char mtext[1];//消息的正文
     };
    

    发送出去的消息必须以一个long型数据打头,作为该消息的标识,后面的数据则没有要求。消息的标识可以是任意长整型数值,但不能是0L,参数msgsz是消息中正文的大小,不包含消息的标识。