【正文】
出版社,給出了系統(tǒng)V消息隊(duì)列相關(guān)的源代碼分析。附錄 3:消息隊(duì)列實(shí)例輸出結(jié)果:current number of bytes on queue is 0number of messages in queue is 0max number of bytes on queue is 16384pid of last msgsnd is 0pid of last msgrcv is 0last msgsnd time is Thu Jan 1 08:00:00 1970last msgrcv time is Thu Jan 1 08:00:00 1970last change time is Sun Dec 29 18:28:20 2002msg uid is 0msg gid is 0//上面剛剛創(chuàng)建一個(gè)新消息隊(duì)列時(shí)的輸出current number of bytes on queue is 1number of messages in queue is 1max number of bytes on queue is 16384pid of last msgsnd is 2510pid of last msgrcv is 0last msgsnd time is Sun Dec 29 18:28:21 2002last msgrcv time is Thu Jan 1 08:00:00 1970last change time is Sun Dec 29 18:28:20 2002msg uid is 0msg gid is 0read from msg queue 1 bytes//實(shí)際讀出的字節(jié)數(shù)current number of bytes on queue is 0number of messages in queue is 0max number of bytes on queue is 16384 //每個(gè)消息隊(duì)列最大容量(字節(jié)數(shù))pid of last msgsnd is 2510pid of last msgrcv is 2510last msgsnd time is Sun Dec 29 18:28:21 2002last msgrcv time is Sun Dec 29 18:28:22 2002last change time is Sun Dec 29 18:28:20 2002msg uid is 0msg gid is 0current number of bytes on queue is 0number of messages in queue is 0max number of bytes on queue is 16388 //可看出超級(jí)用戶可修改消息隊(duì)列最大容量pid of last msgsnd is 2510pid of last msgrcv is 2510 //對(duì)操作消息隊(duì)列進(jìn)程的跟蹤last msgsnd time is Sun Dec 29 18:28:21 2002last msgrcv time is Sun Dec 29 18:28:22 2002last change time is Sun Dec 29 18:28:23 2002 //msgctl()調(diào)用對(duì)msg_ctime有影響msg uid is 8msg gid is 8參考文獻(xiàn): /* max number of bytes on queue */ __kernel_ipc_pid_t msg_lspid。 /* Reuse junk fields for 32 bit */ unsigned long msg_lqbytes。 /* last message in queue,unused */ __kernel_time_t msg_stime。}。 /* pid of last msgsnd */ pid_t q_lrpid。 /* last change time */ unsigned long q_cbytes。 附錄 2:結(jié)構(gòu)msg_queue用來描述消息隊(duì)列頭,存在于系統(tǒng)空間:struct msg_queue { struct kern_ipc_perm q_perm。同樣,消息隊(duì)列可以在幾個(gè)進(jìn)程間復(fù)用,而不管這幾個(gè)進(jìn)程是否具有親緣關(guān)系,這一點(diǎn)與有名管道很相似;但消息隊(duì)列是隨內(nèi)核持續(xù)的,與有名管道(隨進(jìn)程持續(xù))相比,生命力更強(qiáng),應(yīng)用空間更大。printf(msg gid is %d\n,)。()))。printf(pid of last msgrcv is %d\n,)。printf(number of messages in queue is %d\n,)。if(reval==1){ printf(get msg info error\n)。}}void msg_stat(int msgid,struct msqid_ds msg_info){int reval。}msg_stat(msgid,msg_ginfo)。//此處驗(yàn)證超級(jí)用戶可以更改消息隊(duì)列的缺省msg_qbytes//注意這里設(shè)置的值大于缺省值reval=msgctl(msgid,IPC_SET,amp。//從消息隊(duì)列中讀出消息后,輸出消息隊(duì)列屬性msg_stat(msgid,msg_ginfo)。reval=msgrcv(msgid,amp。msg_sbuf,sizeof(),sflags)。=10。if(msgid==1){ printf(msg create error\n)。a39。 }msg_rbuf。 char mtext[1]。key_t key。一般來說,實(shí)際開發(fā)過程中不會(huì)超過這個(gè)限制。三、消息隊(duì)列的限制每個(gè)消息隊(duì)列的容量(所能容納的字節(jié)數(shù))都有限制,該值因系統(tǒng)不同而不同。4)int msgctl(int msqid, int cmd, struct msqid_ds *buf)。造成msgsnd()等待的條件有兩種:msgrcv()解除阻塞的條件有三個(gè):1. 消息隊(duì)列中有了滿足條件的消息; 2. msqid代表的消息隊(duì)列被刪除; 3. 調(diào)用msgrcv()的進(jìn)程被信號(hào)中斷; 調(diào)用返回:成功返回讀出消息的實(shí)際字節(jié)數(shù),否則返回1。 IPC_NOERROR 如果隊(duì)列中滿足條件的消息內(nèi)容大于所請(qǐng)求的msgsz字節(jié),則把該消息截?cái)啵財(cái)嗖糠謱G失。該系統(tǒng)調(diào)用從msgid代表的消息隊(duì)列中讀取一個(gè)消息,并把消息存儲(chǔ)在msgp指向的msgbuf結(jié)構(gòu)中。 key參數(shù)為IPC_PRIVATE; 參數(shù)msgflg可以為以下:IPC_CREAT、IPC_EXCL、IPC_NOWAIT或三者的或結(jié)果。 系統(tǒng)V消息隊(duì)列API共有四個(gè),使用時(shí)需要包括幾個(gè)頭文件:include sys/include sys/include sys/1)int msgget(key_t key, int msgflg)參數(shù)key是一個(gè)鍵值,由ftok獲得;msgflg參數(shù)是一些標(biāo)志位。 int ipc(MSGRCV, int first, int second, int third, void *ptr, long fifth)。 int ipc(MSGGET, int first, int second, int third, void *ptr, long fifth)。 ipc_id=ipc(MSGGET, (int)key, flags,0,NULL,0)。該函數(shù)不直接對(duì)消息隊(duì)列操作,但在調(diào)用ipc(MSGGET,…)或msgget()來獲得消息隊(duì)列描述字前,往往要調(diào)用該函數(shù)。mtype成員代表消息類型,從消息隊(duì)列中讀取消息的一個(gè)重要依據(jù)就是消息的類型;mtext是消息內(nèi)容,當(dāng)然長(zhǎng)度不一定為1。}二、操作消息隊(duì)列對(duì)消息隊(duì)列的操作無非有下面三種類型: 打開或創(chuàng)建消息隊(duì)列消息隊(duì)列的內(nèi)核持續(xù)性要求每個(gè)消息隊(duì)列都在系統(tǒng)范圍內(nèi)對(duì)應(yīng)唯一的鍵值,所以,要獲得一個(gè)消息隊(duì)列的描述字,只需提供該消息隊(duì)列的鍵值即可;注:消息隊(duì)列描述字是由在系統(tǒng)范圍內(nèi)唯一的鍵值生成的,而鍵值可以看作對(duì)應(yīng)系統(tǒng)內(nèi)的一條路經(jīng)。uid_t cuid。 從上圖可以看出,全局?jǐn)?shù)據(jù)結(jié)構(gòu) struct ipc_ids msg_ids 可以訪問到每個(gè)消息隊(duì)列頭的第一個(gè)成員:struct kern_ipc_perm;而每個(gè)struct kern_ipc_perm能夠與具體的消息隊(duì)列對(duì)應(yīng)起來是因?yàn)樵谠摻Y(jié)構(gòu)中,有一個(gè)key_t類型成員key,而key則唯一確定一個(gè)消息隊(duì)列。每個(gè)消息隊(duì)列都有一個(gè)