1. 程式人生 > >對Linux中訊息佇列和訊號量集合的理解

對Linux中訊息佇列和訊號量集合的理解

訊息佇列和訊號量集合同樣作為程序間通訊的重要手段,是LInux程式設計必需理解的內容,但兩者類似的操作和檔案結構讓很多人不能理解其中的原理。下面我來介紹下我的理解:

在使用訊息佇列和訊號量集合前都必須使用的一個函式Key_t ftok(char *pathname,char proj), 其功能是:根據檔名(包含路徑)和專案名返回對應鍵值key,留作建立訊息佇列的引數(這裡可以理解為同一個檔案可以有多個專案,每個專案的key值都不同),學習這個函式時,就應該搞懂該函式的第二個引數專案名,這表明同樣一個檔案可以有不同的專案,當然對應的返回值key也就不一樣了。

建立或開啟訊息佇列函式msgget(key_t key, int msgflg)

,這時傳入key值即可返回對應的訊息佇列描述符。之後想在該訊息佇列中傳送訊息,使用msgsnd(int msqid,struct msgbuf*msgp,int msgsz,int msgflg),引數裡的結構體

struct msgbuf

{

    Long mtype;    //訊息型別>0

    Char mtext[1];  //訊息佇列的首地址

}

表明你的每個訊息必須有一個訊息型別,(可以把一個訊息類比成結構體,或者說python中的字典更為確切),總而言之就是訊息內容前有一個long型的型別表明訊息名稱。

而想要獲取訊號量也是類似的操作,首先通過semget(key_ key ,int nsems, int semflg)

得到對應的訊號量集合描述符,所以訊號量集合和訊息佇列其實是一個重量級的東西。不過需要注意的是函式中的第二個引數表明在建立開啟訊號量集合時,必須確定訊號量集合包含的訊號量個數。這不同於建立訊息佇列。之後的操作函式semop(int semid ,struct sembuf*sops,unsigned nsops)中也有一個類似於訊息佇列中struct msgbuf的結構體

struct sembuf{

unsigned short sem_num;   訊號量在訊號量集合中的索引,第一個為0

short sem_op;    訊號量操作 -+1,獲取還是釋放

short sem_flg;   

操作標誌,取值IPC_NOWAIT:對訊號的操作不能滿足時,semop()不會阻塞,並立即返回,同時設定錯誤資訊。IPC_UNDO:程式結束時(無論正常或不正常)釋放訊號量,這樣做的目的在於避免程式在異常情況下結束時未將鎖定的資源解鎖,造成資源永遠鎖定。

}

其中的sem_num其實和struct msgbuf中的type是一樣的作用,用來表明操作那個訊號量或訊息。

最後畫了一張圖可以清晰的看出我所述的邏輯,如下: