linux环境编程--IPC 之 msg queue
?
?
?
系統(tǒng)調(diào)用:msgget();
原型:int msgget(key_t key, int msgflg);
返回值:如果成功,返回消息隊列標識符
如果失敗,則返回-1:errno=EACCESS(權(quán)限不允許)
EEXIST(隊列已經(jīng)存在,無法創(chuàng)建)
EIDRM(隊列標志為刪除)
ENOENT(隊列不存在)
ENOMEM(創(chuàng)建隊列時內(nèi)存不夠)
ENOSPC(超出最大隊列限制)
?
IPC_CREAT如果內(nèi)核中沒有此隊列,則創(chuàng)建它。
IPC_EXCL當和IPC_CREAT一起使用時,如果隊列已經(jīng)存在,則失敗。
?
下面看一個打開和創(chuàng)建一個消息隊列的例子:
int?
{
?
?
?
?
?
?
}
?
系統(tǒng)調(diào)用msgsnd()
?
系統(tǒng)調(diào)用:msgsnd();
原型:int?
返回值:如果成功,0。
如果失敗,-1:errno=EAGAIN(隊列已滿,并且使用了IPC_NOWAIT)
EACCES(沒有寫的權(quán)限)
EFAULT(msgp地址無效)
EIDRM(消息隊列已經(jīng)刪除)
EINTR(當?shù)却龑懖僮鲿r,收到一個信號)
EINVAL(無效的消息隊列標識符,非正數(shù)的消息類型,或
者無效的消息長度)
ENOMEM(沒有足夠的內(nèi)存復制消息緩沖區(qū))
?
?
?
?
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)
{
?
}
?
}
系統(tǒng)調(diào)用:msgrcv();
原型:int msgrcv(intmsqid,structmsgbuf*msgp,intmsgsz,longmtype,intmsgflg);
返回值:如果成功,則返回復制到消息緩沖區(qū)的字節(jié)數(shù)。
如果失敗,則返回-1:errno=E2BIG(消息的長度大于msgsz,沒有MSG_NOERROR)
EACCES(沒有讀的權(quán)限)
EFAULT(msgp指向的地址是無效的)
EIDRM(隊列已經(jīng)被刪除)
EINTR(被信號中斷)
EINVAL(msgqid無效,或者msgsz小于0)
ENOMSG(使用IPC_NOWAIT,同時隊列中的消息無法滿足要求)
?
?
?
如果調(diào)用中使用了IPC_NOWAIT作為標志,那么當沒有數(shù)據(jù)可以使用時,調(diào)用將把ENOMSG返回到調(diào)用進程中。否則,調(diào)用進程將會掛起,直到隊列中的一條消息滿足msgrcv()的參數(shù)要求。如果當客戶端等待一條消息的時候隊列為空,將會返回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);
}
?
?
系統(tǒng)調(diào)用msgctl()
?
系統(tǒng)調(diào)用: msgctl( ) ;
調(diào)用原型: int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );
返回值: 0 ,如果成功。
- 1,如果失敗:errno = EACCES (沒有讀的權(quán)限同時cmd 是IPC_STAT )
EFAULT (buf 指向的地址無效)
EIDRM (在讀取中隊列被刪除)
EINVAL (msgqid無效, 或者msgsz 小于0 )
EPERM (IPC_SET或者IPC_RMID 命令被使用,但調(diào)用程序沒有寫的權(quán)限)
下面我們看一下可以使用的幾個命令:
IPC_STAT
讀取消息隊列的數(shù)據(jù)結(jié)構(gòu)msqid_ds,并將其存儲在b u f指定的地址中。
IPC_SET
設置消息隊列的數(shù)據(jù)結(jié)構(gòu)msqid_ds中的ipc_perm元素的值。這個值取自buf參數(shù)。
IPC_RMID
從系統(tǒng)內(nèi)核中移走消息隊列。
?
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);
}
};
總結(jié)
以上是生活随笔為你收集整理的linux环境编程--IPC 之 msg queue的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。