天天看點

IPC之SystemV弊端--共享記憶體、信号量和消息隊列共三種

svipc - System V interprocess communication mechanisms

linux實作的System V interprocess communication (IPC)機制包含消息隊列(message queues),信号集(semaphore sets),和共享記憶體(shared memory segments)。

man 7 svipc

SystemV消息通信弊端

在新的應用中很少會用到System V IPC,因為它已經被POSIX IPC取代了。但編寫老程式時仍可能用到。

像管道一樣,IPC存在于核心(實際上是核心記憶體)而不是像FIFO一樣存在于檔案系統中。IPC的集中結構有時合起來叫做IPC對象(其實是信号燈、消息隊列和共享記憶體)。

 每個對象都通過它的辨別符來引用和通路,辨別符是一個正整數,它唯一地辨別出對象本身和它的類型。每個辨別符的類型都是唯一的,但同一辨別符的值可以用于一個消息隊列、一個信号燈和一個共享記憶體區。辨別符稱為該結構上所有其他操作的句柄。IPC結構辨別符不想檔案描述符那樣使用較小的正整數。實際上,随着結構的建立和删除,辨別符的值(正式的名稱叫做槽使用順序号)會不斷增加直至達到一個最大值為止,然後再轉回到0并重新開始。在linux系統中,辨別符聲明為整數,是以它的值最大可能為65535。

     每個IPC結構都有get函數建立,在建立了一個IPC結構之後,使用同一個關鍵字(key)的get函數的後續調用不會建立新結構,但傳回和現在結構相關的辨別符。這可以讓兩個或兩個以上的程序用同一關鍵字key調用get函數以建立一條IPC通道。

    接下來的問題是怎樣確定所有要使用同一IPC結構的程序都使用相同的關鍵字。一種方法為,實際建立結構的程序給get函數傳遞IPC_PRIVATE關鍵字,這能保證建立一個新結構。然後建立IPC結構的程序把傳回的辨別符儲存在其他程序能夠通路的檔案系統中。在父程序fork或exec一個子程序的場合,父程序可以把傳回的辨別符作為一個參數傳遞給建立子程序的函數exec。

     另一種傳遞關鍵字的方法是把它儲存在公共的頭檔案中,這樣一來所有包含了這個頭檔案的程式都能夠通路到相同的關鍵字。這種方法引出的一個問題,沒有程序直到它是正在建立一個新結構呢還是隻通路已經由其他程序建立好的結構。這種方法帶來的另外一個問題是關鍵字可能已經被另外一個無關的程式使用了。結果使用這個關鍵字的程序必須包含處理這種可能性的代碼。

     第三種方法是用ftok函數,這個函數接受一個路徑名和一個稱為項目辨別符的單個字元作為參數,傳回一個關鍵字可以傳遞給get函數。有程式員保證所有的程序實作直到路徑名和項目辨別符。你可以使用前面提到過的方法之一:在公共的頭檔案中包含路徑名和項目辨別符,或者把他們儲存在預定義的配置檔案中。

    不幸的是,ftok有個嚴重的缺陷:它不能保證産生唯一的關鍵字,這一來出現了和前面讨論的第二種方法一樣的問題。在下列情況下,ftok生成唯一的關鍵字:

>>當兩個不同的符号連結到同一檔案上。

>>當路徑名的索引節點的前16個比特位具有相同的值。

>>當系統帶有兩個相同次裝置号的硬碟時,在系統由多個磁盤控制器的情況下才會出現。主裝置号不相同,但次裝置号可以相同。

繼續閱讀