或:
msgrcv手册中详细给出了消息类型取不同值时(>0; <0; =0),调用将返回消息队列中的哪个消息。
msgrcv()解除阻塞的条件有三个:
调用返回:成功返回读出消息的实际字节数,否则返回-1。
3)int msgsnd(int msqid, struct msgbuf *msgp, int msgsz, int msgflg);
向msgid代表的消息队列发送一个消息,即将发送的消息存储在msgp指向的msgbuf结构中,消息的大小由msgze指定。
对发送消息来说,有意义的msgflg标志为IPC_NOWAIT,指明在消息队列没有足够空间容纳要发送的消息时,msgsnd是否等待。造成msgsnd()等待的条件有两种:
msgsnd()解除阻塞的条件有三个:
调用返回:成功返回0,否则返回-1。
4)int msgctl(int msqid, int cmd, struct msqid_ds *buf);
该系统调用对由msqid标识的消息队列执行cmd操作,共有三种cmd操作:IPC_STAT、IPC_SET 、IPC_RMID。
调用返回:成功返回0,否则返回-1。
#include
#include
#include
void msg_stat(int,struct msqid_ds );
void main()
{
int gflags,sflags,rflags;
key_t key;
int msgid;
int reva l;
struct msgsbuf{
? ? ? ? int mtype;
? ? ? ? char mtext[1];
? ? }msg_sbuf;
struct msgmbuf
? ? {
? ? ? ? ? ? int mtype;
? ? ? ? ? ? char mtext[10];
? ? }msg_rbuf;
struct msqid_ds msg_ginfo,msg_sinfo;
char* msgpath="/unix/msgqueue";
key=ftok(msgpath,'a');
gflags=IPC_CREAT|IPC_EXCL;
msgid=msgget(key,gflags|00666);
if(msgid==-1)
{
? ? ? ? ? ? printf("msg create error\n");
? ? ? ? ? ? return;
}
//创建一个消息队列后,输出消息队列缺省属性
msg_stat(msgid,msg_ginfo);
sflags=IPC_NOWAIT;
msg_sbuf.mtype=10;
msg_sbuf.mtext[0]='a';
reva l=msgsnd(msgid,&msg_sbuf,sizeof(msg_sbuf.mtext),sflags);
if(reva l==-1)
{
? ? ? ? ? ? printf("message send error\n");
}
//发送一个消息后,输出消息队列属性
msg_stat(msgid,msg_ginfo);
rflags=IPC_NOWAIT|MSG_NOERROR;
reva l=msgrcv(msgid,&msg_rbuf,4,10,rflags);
if(reva l==-1)
? ? ? ? ? ? printf("read msg error\n");
else
? ? ? ? ? ? printf("read from msg queue %d bytes\n",reva l);
//从消息队列中读出消息后,输出消息队列属性
msg_stat(msgid,msg_ginfo);
msg_sinfo.msg_perm.uid=8;//just a try
msg_sinfo.msg_perm.gid=8;//
msg_sinfo.msg_qbytes=16388;
//此处验证超级用户可以更改消息队列的缺省msg_qbytes
//注意这里设置的值大于缺省值
reva l=msgctl(msgid,IPC_SET,&msg_sinfo);
if(reva l==-1)
{
? ? ? ? ? ? printf("msg set info error\n");
? ? ? ? ? ? return;
}
msg_stat(msgid,msg_ginfo);
//验证设置消息队列属性
reva l=msgctl(msgid,IPC_RMID,NULL);//删除消息队列
if(reva l==-1)
{
? ? ? ? ? ? printf("unlink msg queue error\n");
? ? ? ? ? ? return;
}
}
void msg_stat(int msgid,struct msqid_ds msg_info)
{
int reva l;
sleep(1);//只是为了后面输出时间的方便
reva l=msgctl(msgid,IPC_STAT,&msg_info);
if(reva l==-1)
{
? ? ? ? ? ? printf("get msg info error\n");
? ? ? ? ? ? return;
}
printf("\n");
printf("current number of bytes on queue is %d\n",msg_info.msg_cbytes);
printf("number of messages in queue is %d\n",msg_info.msg_qnum);
printf("max number of bytes on queue is %d\n",msg_info.msg_qbytes);
//每个消息队列的容量(字节数)都有限制MSGMNB,值的大小因系统而异。在创建新的消息队列时,
//msg_qbytes的缺省值就是MSGMNB
printf("pid of last msgsnd is %d\n",msg_info.msg_lspid);
printf("pid of last msgrcv is %d\n",msg_info.msg_lrpid);
printf("last msgsnd time is %s", ctime(&(msg_info.msg_stime)));
printf("last msgrcv time is %s", ctime(&(msg_info.msg_rtime)));
printf("last change time is %s", ctime(&(msg_info.msg_ctime)));
printf("msg uid is %d\n",msg_info.msg_perm.uid);
printf("msg gid is %d\n",msg_info.msg_perm.gid);
}