您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > 消息队列函数(msggetmsgctlmsgsndmsgrcv)及其范例
消息队列函数(msgget、msgctl、msgsnd、msgrcv)及其范例消息队列函数由msgget、msgctl、msgsnd、msgrcv四个函数组成。下面的表格列出了这四个函数的函数原型及其具体说明。1.msgget函数原型msgget(得到消息队列标识符或创建一个消息队列对象)所需头文件#includesys/types.h#includesys/ipc.h#includesys/msg.h函数说明得到消息队列标识符或创建一个消息队列对象并返回消息队列标识符函数原型intmsgget(key_tkey,intmsgflg)函数key0(IPC_PRIVATE):会建立新的消息队列大于0的32位整数:视参数msgflg来确定操作。通常要求传入值此值来源于ftok返回的IPC键值msgflg0:取消息队列标识符,若不存在则函数会报错IPC_CREAT:当msgflg&IPC_CREAT为真时,如果内核中不存在键值与key相等的消息队列,则新建一个消息队列;如果存在这样的消息队列,返回此消息队列的标识符IPC_CREAT|IPC_EXCL:如果内核中不存在键值与key相等的消息队列,则新建一个消息队列;如果存在这样的消息队列则报错函数返回值成功:返回消息队列的标识符出错:-1,错误原因存于error中附加说明上述msgflg参数为模式标志参数,使用时需要与IPC对象存取权限(如0600)进行|运算来确定消息队列的存取权限错误代码EACCES:指定的消息队列已存在,但调用进程没有权限访问它EEXIST:key指定的消息队列已存在,而msgflg中同时指定IPC_CREAT和IPC_EXCL标志ENOENT:key指定的消息队列不存在同时msgflg中没有指定IPC_CREAT标志ENOMEM:需要建立消息队列,但内存不足ENOSPC:需要建立消息队列,但已达到系统的限制如果用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函数原型msgctl(获取和设置消息队列的属性)所需头文件#includesys/types.h#includesys/ipc.h#includesys/msg.h函数说明获取和设置消息队列的属性函数原型intmsgctl(intmsqid,intcmd,structmsqid_ds*buf)函数传入值msqid消息队列标识符cmdIPC_STAT:获得msgid的消息队列头数据到buf中IPC_SET:设置消息队列的属性,要设置的属性需先存储在buf中,可设置的属性包括:msg_perm.uid、msg_perm.gid、msg_perm.mode以及msg_qbytesbuf:消息队列管理结构体,请参见消息队列内核结构说明部分函数返回值成功:0出错:-1,错误原因存于error中错误代码EACCESS:参数cmd为IPC_STAT,确无权限读取该消息队列EFAULT:参数buf指向无效的内存地址EIDRM:标识符为msqid的消息队列已被删除EINVAL:无效的参数cmd或msqidEPERM:参数cmd为IPC_SET或IPC_RMID,却无足够的权限执行3.msgsnd函数原型msgsnd(将消息写入到消息队列)所需头文件#includesys/types.h#includesys/ipc.h#includesys/msg.h函数说明将msgp消息写入到标识符为msqid的消息队列函数原型intmsgsnd(intmsqid,constvoid*msgp,size_tmsgsz,intmsgflg)函数传入值msqid消息队列标识符msgp发送给队列的消息。msgp可以是任何类型的结构体,但第一个字段必须为long类型,即表明此发送消息的类型,msgrcv根据此接收消息。msgp定义的参照格式如下:structs_msg{/*msgp定义的参照格式*/longtype;/*必须大于0,消息类型*/charmtext[256];/*消息正文,可以是其他任何类型*/}msgp;msgsz要发送消息的大小,不含消息类型占用的4个字节,即mtext的长度msgflg0:当消息队列满时,msgsnd将会阻塞,直到消息能写进消息队列IPC_NOWAIT:当消息队列已满的时候,msgsnd函数不等待立即返回IPC_NOERROR:若发送的消息大于size字节,则把该消息截断,截断部分将被丢弃,且不通知发送进程。函数返回值成功:0出错:-1,错误原因存于error中错误代码EAGAIN:参数msgflg设为IPC_NOWAIT,而消息队列已满EIDRM:标识符为msqid的消息队列已被删除EACCESS:无权限写入消息队列EFAULT:参数msgp指向无效的内存地址EINTR:队列已满而处于等待情况下被信号中断EINVAL:无效的参数msqid、msgsz或参数消息类型type小于0msgsnd()为阻塞函数,当消息队列容量满或消息个数满会阻塞。消息队列已被删除,则返回EIDRM错误;被信号中断返回E_INTR错误。如果设置IPC_NOWAIT消息队列满或个数满时会返回-1,并且置EAGAIN错误。msgsnd()解除阻塞的条件有以下三个条件:①不满足消息队列满或个数满两个条件,即消息队列中有容纳该消息的空间。②msqid代表的消息队列被删除。③调用msgsnd函数的进程被信号中断。4.msgrcv函数原型msgrcv(从消息队列读取消息)所需头文件#includesys/types.h#includesys/ipc.h#includesys/msg.h函数说明从标识符为msqid的消息队列读取消息并存于msgp中,读取后把此消息从消息队列中删除函数原型ssize_tmsgrcv(intmsqid,void*msgp,size_tmsgsz,longmsgtyp,intmsgflg);函数传入值msqid消息队列标识符msgp存放消息的结构体,结构体类型要与msgsnd函数发送的类型相同msgsz要接收消息的大小,不含消息类型占用的4个字节msgtyp0:接收第一个消息0:接收类型等于msgtyp的第一个消息0:接收类型等于或者小于msgtyp绝对值的第一个消息msgflg0:阻塞式接收消息,没有该类型的消息msgrcv函数一直阻塞等待IPC_NOWAIT:如果没有返回条件的消息调用立即返回,此时错误码为ENOMSGIPC_EXCEPT:与msgtype配合使用返回队列中第一个类型不为msgtype的消息IPC_NOERROR:如果队列中满足条件的消息内容大于所请求的size字节,则把该消息截断,截断部分将被丢弃函数返回值成功:实际读取到的消息数据长度出错:-1,错误原因存于error中错误代码E2BIG:消息数据长度大于msgsz而msgflag没有设置IPC_NOERROREIDRM:标识符为msqid的消息队列已被删除EACCESS:无权限读取该消息队列EFAULT:参数msgp指向无效的内存地址ENOMSG:参数msgflg设为IPC_NOWAIT,而消息队列中无消息可读EINTR:等待读取队列内的消息情况下被信号中断msgrcv()解除阻塞的条件有以下三个:①消息队列中有了满足条件的消息。②msqid代表的消息队列被删除。③调用msgrcv()的进程被信号中断。消息队列使用程序范例5.消息队列控制范例msgctl.c源代码如下:#includestdio.h#includestring.h#includeunistd.h#includesys/ipc.h#includesys/msg.h#includeerror.h#defineTEXT_SIZE512structmsgbuf{longmtype;charmtext[TEXT_SIZE];};intmain(intargc,char**argv){intmsqid;structmsqid_dsinfo;structmsgbufbuf;structmsgbufbuf1;intflag;intsendlength,recvlength;msqid=msgget(IPC_PRIVATE,0666);if(msqid0){perror(getipc_iderror);return-1;}buf.mtype=1;strcpy(buf.mtext,happynewyear!);sendlength=sizeof(structmsgbuf)-sizeof(long);flag=msgsnd(msqid,&buf,sendlength,0);if(flag0){perror(sendmessageerror);return-1;}buf.mtype=3;strcpy(buf.mtext,goodbye!);sendlength=sizeof(structmsgbuf)-sizeof(long);flag=msgsnd(msqid,&buf,sendlength,0);if(flag0){perror(sendmessageerror);return-1;}flag=msgctl(msqid,IPC_STAT,&info);if(flag0){perror(getmessagestatuserror);return-1;}printf(uid:%d,gid=%d,cuid=%d,cgid=%d\n,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\n,info.msg_perm.mode&0777,info.msg_cbytes,info.msg_qnum,info.msg_qbytes);system(ipcs-q);recvlength=sizeof(structmsgbuf)-sizeof(long);memset(&buf1,0x00,sizeof(structmsgbuf));flag=msgrcv(msqid,&buf1,recvlength,3,0);if(flag0){perror(recvmessageerror);return-1;}printf(type=%d,message=%s\n,buf1.mtype,buf1.mtext);flag=msgctl(msqid,IPC_RMID,NULL);if(flag0){perror(rmmessagequeueerror);return-1;}system(ipcs-q);return0;}编译gccmsgctl.c–omsgctl。执行./msg,执行结果如下:uid:1008,gid=1003,cuid=1008,cgid=1003read-write:666,cbytes=1024,qnum=2,qbytes=163840------MessageQueues--------keymsqidownerpermsused-bytesmessages0x0000000065536zjkf66610242type=3,message=goodbye!------MessageQueues--------keymsqidownerpermsused-bytesmessages6.两
本文标题:消息队列函数(msggetmsgctlmsgsndmsgrcv)及其范例
链接地址:https://www.777doc.com/doc-2236689 .html