系统调用:msgget();
原型:int msgget(key_t key, int msgflg);
返回值:如果成功,返回消息队列标识符
如果失败,则返回-1:errno=EACCESS(权限不允许)
EEXIST(队列已经存在,无法创建)
EIDRM(队列标志为删除)
ENOENT(队列不存在)
ENOMEM(创建队列时内存不够)
ENOSPC(超出最大队列限制)
IPC_CREAT如果内核中没有此队列,则创建它。
IPC_EXCL当和IPC_CREAT一起使用时,如果队列已经存在,则失败。
下面看一个打开和创建一个消息队列的例子:
int
{
}
系统调用msgsnd()
系统调用:msgsnd();
原型:int
返回值:如果成功,0。
如果失败,-1:errno=EAGAIN(队列已满,并且使用了IPC_NOWAIT)
EACCES(没有写的权限)
EFAULT(msgp地址无效)
EIDRM(消息队列已经删除)
EINTR(当等待写操作时,收到一个信号)
EINVAL(无效的消息队列标识符,非正数的消息类型,或
者无效的消息长度)
ENOMEM(没有足够的内存复制消息缓冲区)
int send_message(int qid, struct mymsgbuf *qbuf)
{
intresult,length;
/*The length is essentially the size of the structure minus sizeof(mtype)*/
length=sizeof(structmymsgbuf)-sizeof(long);
if((result = msgsnd(qid, qbuf, length, 0))==-1)
{
}
}
系统调用:msgrcv();
原型:int msgrcv(intmsqid,structmsgbuf*msgp,intmsgsz,longmtype,intmsgflg);
返回值:如果成功,则返回复制到消息缓冲区的字节数。
如果失败,则返回-1:errno=E2BIG(消息的长度大于msgsz,没有MSG_NOERROR)
EACCES(没有读的权限)
EFAULT(msgp指向的地址是无效的)
EIDRM(队列已经被删除)
EINTR(被信号中断)
EINVAL(msgqid无效,或者msgsz小于0)
ENOMSG(使用IPC_NOWAIT,同时队列中的消息无法满足要求)
如果调用中使用了IPC_NOWAIT作为标志,那么当没有数据可以使用时,调用将把ENOMSG返回到调用进程中。否则,调用进程将会挂起,直到队列中的一条消息满足msgrcv()的参数要求。如果当客户端等待一条消息的时候队列为空,将会返回EIDRM。如果进程在等待消息的过程中捕捉到一个信号,则返回EINTR。
int read_message(int qid,long type,struct mymsgbuf*qbuf)
{
intresult,length;
/*The length is essentially the size of the structure minus sizeof(mtype)*/
length=sizeof(struct
if((result=msgrcv(qid,qbuf,length,type,0))==-1)
{
return(-1);
}
return(result);
}
int
{
int
if((result=msgrcv(qid,NULL,0,type,IPC_NOWAIT))==-1)
{
if(errno==E2BIG)
return(TRUE);
}
return(FALSE);
}
系统调用msgctl()
系统调用: msgctl( ) ;
调用原型: int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );
返回值: 0 ,如果成功。
- 1,如果失败:errno = EACCES (没有读的权限同时cmd 是IPC_STAT )
EFAULT (buf 指向的地址无效)
EIDRM (在读取中队列被删除)
EINVAL (msgqid无效, 或者msgsz 小于0 )
EPERM (IPC_SET或者IPC_RMID 命令被使用,但调用程序没有写的权限)
下面我们看一下可以使用的几个命令:
IPC_STAT
读取消息队列的数据结构msqid_ds,并将其存储在b u f指定的地址中。
IPC_SET
设置消息队列的数据结构msqid_ds中的ipc_perm元素的值。这个值取自buf参数。
IPC_RMID
从系统内核中移走消息队列。
int get_queue_ds( int qid, struct msgqid_ds *qbuf )
{
if( msgctl( qid, IPC_STAT, qbuf) == -1)
{
return(-1);
}
return(0);
}
int change_queue_mode(int qid, char *mode )
{
struct msqid_ds tmpbuf;
/* Retrieve a current copy of the internal data structure */
get_queue_ds( qid, &tmpbuf);
/* Change the permissions using an old trick */
sscanf(mode, "%ho", &tmpbuf.msg_perm.mode);
/* Update the internal data structure */
if( msgctl( qid, IPC_SET, &tmpbuf) == -1)
{
return(-1);
}
return(
}
int remove_queue(int qid )
{
if( msgctl( qid, IPC_RMID, 0) == -1)
{
return(-1);
}
return(0);
}
};