【正文】
員的長(zhǎng)度(即消息內(nèi)容的長(zhǎng)度),msgtyp為請(qǐng)求讀取的消息類型;讀消息標(biāo)志msgflg可以為以下幾個(gè)常值的或:調(diào)用返回:成功返回消息隊(duì)列描述字,否則返回1。該調(diào)用返回與健值key相對(duì)應(yīng)的消息隊(duì)列描述字。 正如ipc手冊(cè)所說(shuō)的:ipc()是linux所特有的,編寫(xiě)程序時(shí)應(yīng)注意程序的移植性問(wèn)題; 與該操作對(duì)應(yīng)的系統(tǒng)V調(diào)用為:int msgrcv( first,(struct msgbuf*)ptr, second, fifth,third), 注:本人不主張采用系統(tǒng)調(diào)用ipc(),而更傾向于采用系統(tǒng)V或者POSIX進(jìn)程間通信API。 int ipc(MSGSND, int first, int second, int third, void *ptr, long fifth)。與該操作對(duì)應(yīng)的系統(tǒng)V調(diào)用為:int msgget( (key_t)first,second)。 …linux為操作系統(tǒng)V進(jìn)程間通信的三種方式(消息隊(duì)列、信號(hào)燈、共享內(nèi)存區(qū))提供了一個(gè)統(tǒng)一的用戶界面:int ipc(unsigned int call, int first, int second, int third, void *ptr, long fifth)。典型的調(diào)用代碼是: key=ftok(path_ptr, 39。因此,對(duì)于發(fā)送消息來(lái)說(shuō),首先預(yù)置一個(gè)msgbuf緩沖區(qū)并寫(xiě)入消息類型和內(nèi)容,調(diào)用相應(yīng)的發(fā)送函數(shù)即可;對(duì)讀取消息來(lái)說(shuō),首先分配這樣一個(gè)msgbuf緩沖區(qū),然后把消息讀入該緩沖區(qū)即可。 讀寫(xiě)操作消息讀寫(xiě)操作非常簡(jiǎn)單,對(duì)開(kāi)發(fā)人員來(lái)說(shuō),每個(gè)消息都類似如下的數(shù)據(jù)結(jié)構(gòu):struct msgbuf{long mtype。gid_t cgid。kern_ipc_perm結(jié)構(gòu)如下:struct kern_ipc_perm{ //內(nèi)核中記錄消息隊(duì)列的全局?jǐn)?shù)據(jù)結(jié)構(gòu)msg_ids能夠訪問(wèn)到該結(jié)構(gòu); key_t key。隊(duì)列頭中包含了該消息隊(duì)列的大量信息,包括消息隊(duì)列鍵值、用戶ID、組ID、消息隊(duì)列中消息數(shù)目等等,甚至記錄了最近對(duì)消息隊(duì)列讀寫(xiě)進(jìn)程的ID。一、消息隊(duì)列基本概念1. 系統(tǒng)V消息隊(duì)列是隨內(nèi)核持續(xù)的,只有在內(nèi)核重起或者顯示刪除一個(gè)消息隊(duì)列時(shí),該消息隊(duì)列才會(huì)真正被刪除。在本系列專題的序(深刻理解Linux進(jìn)程間通信(IPC))中,提到對(duì)于消息隊(duì)列、信號(hào)燈、以及共享內(nèi)存區(qū)來(lái)說(shuō),有兩個(gè)實(shí)現(xiàn)版本:POSIX的以及系統(tǒng)V的。對(duì)消息隊(duì)列有寫(xiě)權(quán)限的進(jìn)程可以向中按照一定的規(guī)則添加新消息;對(duì)消息隊(duì)列有讀權(quán)限的進(jìn)程則可以從消息隊(duì)列中讀走消息。消息隊(duì)列(也叫做報(bào)文隊(duì)列)能夠克服早期unix通信機(jī)制的一些缺點(diǎn)。作為早期unix通信機(jī)制之一的信號(hào)能夠傳送的信息量有限,后來(lái)雖然POSIX ,使得信號(hào)在傳遞信息量方面有了相當(dāng)程度的改進(jìn),但是信號(hào)這種通信方式更像即時(shí)的通信方式,它要求接受信號(hào)的進(jìn)程在某個(gè)時(shí)間范圍內(nèi)對(duì)信號(hào)做出反應(yīng),因此該信號(hào)最多在接受信號(hào)進(jìn)程的生命周期內(nèi)才有意義,信號(hào)所傳遞的信息是接近于隨進(jìn)程持續(xù)的概念(processpersistent),見(jiàn)附錄 1;管道及有名管道及有名管道則是典型的隨進(jìn)程持續(xù)IPC,并且,只能傳送無(wú)格式的字節(jié)流無(wú)疑會(huì)給應(yīng)用程序開(kāi)發(fā)帶來(lái)不便,另外,它的緩沖區(qū)大小也受到限制。消息隊(duì)列是隨內(nèi)核持續(xù)的(參見(jiàn)附錄 1)。Linux內(nèi)核()支持POSIX信號(hào)燈、POSIX共享內(nèi)存區(qū)以及POSIX消息隊(duì)列,(),還沒(méi)有提供對(duì)POSIX進(jìn)程間通信API的支持,不過(guò)應(yīng)該只是時(shí)間上的事。因此系統(tǒng)中記錄消息隊(duì)列的數(shù)據(jù)結(jié)構(gòu)(struct ipc_ids msg_ids)位于內(nèi)核中,系統(tǒng)中的所有消息隊(duì)列都可以在結(jié)構(gòu)msg_ids中找到訪問(wèn)入口。讀者可以訪問(wèn)這些信息,也可以設(shè)置其中的某些信息。 //該鍵值則唯一對(duì)應(yīng)一個(gè)消息隊(duì)列 uid_t uid。mode_t mode。char mtext[1]。 獲得或設(shè)置消息隊(duì)列屬性:消息隊(duì)列的信息基本上都保存在消息隊(duì)列頭中,因此,可以分配一個(gè)類似于消息隊(duì)列頭的結(jié)構(gòu)(struct msqid_ds,見(jiàn)附錄 2),來(lái)返回消息隊(duì)列的屬性;同樣可以設(shè)置該數(shù)據(jù)結(jié)構(gòu)。a39。第一個(gè)參數(shù)指明對(duì)IPC對(duì)象的操作方式,對(duì)消息隊(duì)列而言共有四種操作:MSGSND、MSGRCV、MSGGET以及MSGCTL,分別代表向消息隊(duì)列發(fā)送消息、從消息隊(duì)列讀取消息、打開(kāi)或創(chuàng)建消息隊(duì)列、控制消息隊(duì)列;first參數(shù)代表唯一的IPC對(duì)象;下面將介紹四種操作。 與該操作對(duì)應(yīng)的系統(tǒng)V調(diào)用為:int msgsnd( first, (struct msgbuf*)ptr, second, third)。原因如下: 該系統(tǒng)調(diào)用的實(shí)現(xiàn)不過(guò)是把系統(tǒng)V IPC函數(shù)進(jìn)行了封裝,沒(méi)有任何效率上的優(yōu)勢(shì); 在以下兩種情況下,該調(diào)用將創(chuàng)建一個(gè)新的消息隊(duì)列:注:參數(shù)key設(shè)置成常數(shù)IPC_PRIVATE并不意味著其他進(jìn)程不能訪問(wèn)該消息隊(duì)列,只意味著即將創(chuàng)建新的消息隊(duì)列。 IPC_NOWAIT 如果沒(méi)有滿足條件的消息,調(diào)用立即返回,此時(shí),errno=ENOMSG 0。向msgid代表的消息隊(duì)列發(fā)送一個(gè)消息,即將發(fā)送的消息存儲(chǔ)在msgp指向的msgbuf結(jié)構(gòu)中,消息的大小由msgze指定。 當(dāng)前消息隊(duì)列的消息數(shù)(單位個(gè))不小于消息隊(duì)列的總?cè)萘浚▎挝蛔止?jié)數(shù)),此時(shí),雖然消息隊(duì)列中的消息數(shù)目很多,但基本上都只有一個(gè)字節(jié)。1. IPC_STAT:該命令用來(lái)獲取消息隊(duì)列信息,返回的信息存貯在buf指向的msqid結(jié)構(gòu)中; 2. IPC_SET:該命令用來(lái)設(shè)置消息隊(duì)列的屬性,要設(shè)置的屬性存儲(chǔ)在buf指向的msqid結(jié)構(gòu)中;可設(shè)置屬性包括:、同時(shí),也影響msg_ctime成員。另一個(gè)限制是每個(gè)消息隊(duì)列所能容納的最大消息數(shù):在redhad ,該限制是受消息隊(duì)列容量制約的:消息個(gè)數(shù)要小于消息隊(duì)列的容量(字節(jié)數(shù))。include sys/include sys/include void msg_stat(int,struct msqid_ds )。int reval。struct msgmbuf { int mtype。char* msgpath=/unix/msgqueue。gflags=IPC_CREAT|IPC_EXCL。}//創(chuàng)建一個(gè)消息隊(duì)列后,輸出消息隊(duì)列缺省屬性msg_stat(msgid,msg_ginfo)。a39。}//發(fā)送一個(gè)消息后,輸出消息隊(duì)列屬性msg_stat(msgid,msg_ginfo)。if(reval==1) printf(read msg error\n)。//just a try=8。if(reval==1){ printf(msg set info error\n)。//刪除消息隊(duì)列if(reval==1){ printf(unlink msg queue error\n)。//只是為了后面輸出時(shí)間的方便reval=msgctl(msgid,IPC_STAT,amp。}printf(\n)。//每個(gè)消息隊(duì)列的容量(字節(jié)數(shù))都有限制MSGMNB,值的大小因系統(tǒng)而異。()))。()))。小結(jié):消息隊(duì)列與管道以及有名管道相比,具有更大的靈活性,首先,它提供有格式字節(jié)流,有利于減少開(kāi)發(fā)人員的工作量;其次,消息具有類型,在實(shí)際應(yīng)用中,可作為優(yōu)先級(jí)使用。如管道和有名管道; 2. 隨內(nèi)核持續(xù):IPC一直持續(xù)到內(nèi)核重新自舉或者顯示刪除該對(duì)象為止。 /* last msgsnd time */ time_t q_rtime。 /* number of messages in queue */ unsigned long q_qbytes。 struct list_head q_receivers。 struct msg *msg_first。 /* last msgrcv time */ __kernel_time_t msg_ctime。 /* current number of bytes on queue */ unsigned short msg_qnum。 /* last receive pid */}。對(duì)POSIX以及系統(tǒng)V消息隊(duì)列都有闡述,對(duì)Linux環(huán)境下的程序開(kāi)發(fā)有極大的啟發(fā)意義。 ,主要闡述linux下對(duì)文件的操作,詳細(xì)介紹了對(duì)文件的存取權(quán)限位,對(duì)IPC對(duì)象的存取權(quán)限同樣具有很好的借鑒意義。t agree with the disciplinary action your employer has taken against youappealeddamagesbased agreement. In England and Wales, your solicitor can39。re clear about the terms of the agreement. It might be bes