詳解Unix消息隊列知識
學習了很久的Unix操作系統(tǒng)的知識,今天,我們來給大家介紹下Unix消息隊列相關(guān)方面的知識。希望大家可以好好的學習。
在Unix操作系統(tǒng)的內(nèi)部結(jié)構(gòu)中,含有消息機構(gòu),即所有的消息都放在內(nèi)核中,并且它們都有一個相應的Unix消息隊列號。消息機構(gòu)允許進程發(fā)送一個消息到任意其它進程,從而實現(xiàn)系統(tǒng)中進程間的通信。
一、Unix操作系統(tǒng)中的消息機構(gòu)
消息是一個格式化的可變長度的信息單元。它有如下屬性:(1)長整數(shù)類型 (2)消息的數(shù)據(jù)長度 (3)數(shù)據(jù)。由于消息的長度是可變的,故將消息分為消息首部和消息數(shù)據(jù)兩部分。在消息首部中,記錄著消息的類型和大小,指向消息數(shù)據(jù)區(qū)的指針,Unix消息隊列的鏈接指針等。
每個消息隊列有一個稱為 key的名稱,如同用戶文件描述符一樣,每個Unix消息隊列還有一個消息隊列描述符。此外,在一個系統(tǒng)中,可能有若干個Unix消息隊列,所有Unix消息隊列的頭標組成一個數(shù)組。
1. Unix操作系統(tǒng)建立或返回Unix消息隊列描述符
進程可用系統(tǒng)調(diào)用megget來建立或返回Unix消息隊列的描述符。該系統(tǒng)調(diào)用的語法格式為:
- int megget(key,msgflg)
- key_t key;
- int megflg;
其中,key是Unix消息隊列的名字;msgflg是用戶設(shè)置的標志。如果IPC_CREAT表示系統(tǒng)無以key命名的消息隊列,則建立消息隊列標識符;若已存在,則返回Unix消息隊列描述符msgid。
對于系統(tǒng)調(diào)用,核心將搜索Unix消息隊列頭標數(shù)組,確定是否有指定關(guān)鍵字的Unix消息隊列。若無,核心將分配一新的隊列結(jié)構(gòu),并返回給用戶一個Unix消息隊列描述符;否則,它只是檢查Unix消息隊列的許可權(quán)之后便返回。
2.Unix操作系統(tǒng)消息的發(fā)送
進程可用megsnd( )系統(tǒng)調(diào)用來發(fā)送一個消息,并將它鏈入Unix消息隊列的尾部。該系統(tǒng)調(diào)用的語法格式如下:
- int msgsnd(msgid,msgp,msgsz,msgflg)
- int msgid;
- struct msgbuf * msgp;
- int msgsz,msgflg;
其中,msgid是由msgget返回的Unix消息隊列描述符;msgp指向包含這條消息的結(jié)構(gòu),該結(jié)構(gòu)由如下兩個成員組成:
- struct msgbuf
- { long mtype; /* 消息類型 */
- char mtext[ ]; /* 消息的文本 */ }
msgsz是mtext的字節(jié)長度;msgflg規(guī)定了當無內(nèi)存空間來存儲消息時,進程等待還是立即返回。
對于msgsnd( )系統(tǒng)調(diào)用,核心檢查消息隊列描述符和許可權(quán)是否合法;消息長度是否超過系統(tǒng)規(guī)定的長度,若過長,進程睡眠等待出現(xiàn)足夠大的空間,通過檢查后,核心為消息分配消息數(shù)據(jù)區(qū),并將消息從用戶空間拷貝到消息數(shù)據(jù)區(qū),分配消息首部,將它鏈入該Unix消息隊列的尾部,在消息首部填寫消息類型,大小以及指向消息數(shù)據(jù)區(qū)的指針,還有修改消息隊列的頭標中的數(shù)據(jù)。然后喚醒在等待消息到來的隊列中睡眠的進程。
3. Unix操作系統(tǒng)消息的接收
進程可用msgrcv( )系統(tǒng)調(diào)用,從Unix消息隊列中讀一條消息,語法格式為:
- int msgrcv(msgid,msgp,msgsz,msgtyp,msgflg)
- int msgid,msgsz,msgflg;
- struct msgbuf * msgp;
- long msgtyp;
其中,msgid,msgp,msgsz,msgflg與msgsnd相似,msgtype是規(guī)定用戶想讀的消息類型。
對于msgrcv( )系統(tǒng)調(diào)用是先由核心檢查消息隊列標識符和許可權(quán),接著根據(jù)msgtyp分三種情況處理。
(1) msgtyp=0,核心尋找Unix消息隊列中的第一個消息,并將它返回給調(diào)用進程;
(2)msgtyp為正整數(shù),核心返回給類型的第一個消息;
(3)msgtyp為負整數(shù),核心應在其類型值小于或等于msgtyp絕對值的所有消息中,選擇類型最低的第一消息返回。
如果所返回的消息的大小等于或小于用戶請求,核心便將消息正文拷貝到用戶區(qū),再從隊列中刪除該消息,并喚醒睡眠的發(fā)送進程;如果消息比用戶要求的大,則系統(tǒng)返回錯誤信息。
4. Unix操作系統(tǒng)Unix消息隊列的操縱
可利用msgctl( )系統(tǒng)調(diào)用,來改變Unix消息隊列的屬性,即擁有者,許可權(quán)等。其語法格式如下:
- int msgctl(msgid,cmd,buf)
- int msgid,cmd;
- struct msgid_ds * buf;
其中,cmd是規(guī)定的命令;buf是用戶緩沖區(qū)地址,用戶用它來存放控制參數(shù)和查詢結(jié)果。命令可分為三類:(1)用于查詢有關(guān)Unix消息隊列的情況。(2)用于改變有關(guān)Unix消息隊列的屬性。(3)消除Unix消息隊列的標識符。
二、Unix操作系統(tǒng)多路復用消息
在客戶-服務員模型中,一個服務員往往對應多個客戶。這時我們可以利用消息的類型參量,讓多個進程把消息放入同一個隊列中,以便Unix消息隊列能夠多路復用。如圖2 所示,我們只要把type置為1,以表示消息是從客戶流向服務員的。
如果客戶把它的進程號作為消息的一部分傳遞,那么服務員只要把客戶進程號作為其消息類型,把它的消息發(fā)送給客戶進程。每個客戶進程都把msgrcv的參數(shù)msgtyp置為其進程號。
這樣,我們就介紹玩了Unix操作系統(tǒng)的Unix消息隊列的知識。
【編輯推薦】