消息队列

来源:互联网 发布:中国外来物种数据库 编辑:程序博客网 时间:2024/06/05 19:37




第一个函数:
#include<sys/msg.h>
int msgget(key_t    key,int   msgflg);
功能:创建一个消息队列或取得一个已经存在的消息队列。
返回值:成功返回消息队列的标示符(ID),失败为-1;
参数:
 _key :
1.       消息队列的键值,为IPC_PRIVATE  意思就是创建一个只能被创建进程读写的消息队列。
2.       不是IPC_PRIVATE .则我们可以指定一个值6666,还可以用ftok();函数来获得一个唯一的键值。(ftok()函数见其它文章);
_msgflg : 创建消息队列的创建方式或权限。
     创建方式有:IPC_CREAT 如果内存不存在则创建一个消息队列,否则取得。
                 IPC_EXCL 只有消息队列不存在的时候,新的消息队列才会被创建,否则会产生错误。




第二个函数:
#include<sys/msg.h>
 
Int msgsnd(int msgid,struct  msgbuf   *msgp ,int   msgsz,   int  msgflg);
功能:往队列中发送一个消息。
返回值:成功返回0,失败返回-1;
参数:
 msgid  消息表识id 也就是msgget()函数的返回值。
msgp   :指向消息缓冲区的指针,该结构体为
struct mymesg {
      long  mtype;      /* positive message type  消息的类型必须 > 0 */
      char  mtext[512]; /* message data, of length nbytes  存放消息数据内容*/
};
msgsz, :是消息的字节大小,不包含消息类型的长度(4个字节)
msgflg   :可以设置为0;或者使用IPC_NOWAIT,如果消息队列已经满了,那么次消息就不会写到消息队列中, 控制将返回到对于进程中。如果没有指明,调用进程会被挂起,直到消息可以写到消息队列中。的消息就从队列中删除了。




msgrcv();
格式:#include<sys/msg.h>
   int msgrcv(int  msgid ,  struct   msgbuf   *msgp,int  msgsz , long  mtype,int  msgflg );     
功能:   读取消息,从消息队列中读走消息,是读走不是读取,也就是读完之后没有了,这种机制类似于管道。  
返回值:成功返回拷贝到mtext数组的实际字节数,失败返回-1;
参数:
msgid :  消息队列的id号
 msgp :是我们要读到的消息数据存储消息的地址。
msgsz  是消息的长度不包含mtype 的长度 ,我们可以这样算:
      msgsz=sizeof(struct   msgbuf)-sizeof(long);
mtype  是我们要从消息队列中读取的消息的类型。如果此值为0,则会读取时间最长的那一条消息,不论是什么类型,也就是我们第一个写入消息队列中的消息。
msgflg  可以设置为0,代表该进程将一直阻塞,直到有消息可读停止。但我们可以吧该值设为IPC_NOWAIT  表示,如果没有消息可读时,则立刻返回-1,进程被挂起。
MSG_NOERROR,如果函数取得的消息长度大于msgsz,将只返回msgsz 长度的信息,剩下的部分被丢弃了。如果不指定这个参数,E2BIG 将被返回,而消息则留在队列中不被取出。当消息从队列内取出后,相应的消息就从队列中删除了。






 #include<sys/msg.h>
int  msgctl(int  msgid,  int  cmd  ,struct   msgqid _ds    *buf);
功能:对消息队列的控制处理函数。
返回值:成功返回0,失败返回-1.
参数:
 msgid   消息队列的ID,也就是msgget()函数的返回值。
cmd   命令,对消息队列的处理
     IPC_RMID  从系统内核中删除消息队列,相当于我们在终端输入ipcrm   -q  消息队列id
IPC_STAT  获取消息队列的详细消息。包含权限,各种时间,id等
IPC_SET   设置消息队列的信息。
 
buf: 存放消息队列状态的结构体的地址。




errno被设为以下的某个值
[对于msgsnd]
EACCES:调用进程在消息队列上没有写权能,同时没有CAP_IPC_OWNER权能
EAGAIN:由于消息队列的msg_qbytes的限制和msgflg中指定IPC_NOWAIT标志,消息不能被发送
EFAULT:msgp指针指向的内存空间不可访问
EIDRM:消息队列已被删除
EINTR:等待消息队列空间可用时被信号中断
EINVAL:参数无效
ENOMEM:系统内存不足,无法将msgp指向的消息拷贝进来
[对于msgrcv]
E2BIG:消息文本长度大于msgsz,并且msgflg中没有指定MSG_NOERROR
EACCES:调用进程没有读权能,同时没具有CAP_IPC_OWNER权能
EAGAIN:消息队列为空,并且msgflg中没有指定IPC_NOWAIT
EFAULT:msgp指向的空间不可访问
EIDRM:当进程睡眠等待接收消息时,消息已被删除
EINTR:当进程睡眠等待接收消息时,被信号中断
EINVAL:参数无效
ENOMSG:msgflg中指定了IPC_NOWAIT,同时所请求类型的消息不存在




ipcs  -q 查看队列创建
用ipcrm    –q   msgid号 删除
0 0