歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Unix知識 >> Unix基礎知識

UNIX環境高級編程:IPC總結

IPC主要包括:管道,消息隊列,信號量,共享內存, 套接字(SOCKET)。

一、IPC對象的持久性

每種IPC機制都會借助一種數據結構,這種數據結構的實例稱為該IPC機制的對象(相應的,用於同步互斥的數據結構的實體也可以稱為該機制的對象)。理清IPC對象的持久性,有助於理解相應的IPC的工作機制。

1.對象持久性

大致上IPC對象的持久性可以分為三種:

進程持久性:具有這種持久性的對象在持有它的最後一個進程關閉了該對象時就會消失。

內核持久性:具有這種持久性的對象在兩種情形下會消失,(1)系統重啟(2)它被顯式的刪除

文件系統持久性:具有這種持久性的對象只有在它被顯式刪除時才會消失。

下表是常見的IPC對象以及用於同步互斥的對象的持久性

從表中看沒有一種對象的持久性是文件系統的。這也是合理的,因為很少有進程能不受系統重啟的影響;而且使用文件系統持久性也可能會降低該IPC機制的性能。

2.調用fork,exec,_exit對IPC對象及同步互斥對象的影響

二、System V IPC

System V IPC包含:

System V消息隊列

System V信號量

System V共享內存區

System V IPC具有一些共同的屬性,使用key_t類型的值作為其名字;每個IPC對象有一個與之關聯的ipc_perm結構、IPC權限。

1.System V IPC函數匯總

2.key_t鍵和ftok函數

三種類型的System V IPC使用key_t值作為他們的名字。頭文件<sys/types.h>把key_t這個數據類型定義為一個整數,它通常是一個至少32位的整數。這些整數值通常是ftok函數賦賦予的。

函數ftok把一個已經存在的路徑和一個整數標識符轉換為一個key_t值,叫IPC鍵(IPC key).

ftok典型的實現調用stat函數,然後組合以下三個值:

1. pathname所在文件系統的信息;

2. 該文件在本文件系統內的索引節點號;

3. id的低序8位;

如果pathname不存在或者當前進程不能訪問該文件,則ftok返回-1,另外需要注意的是其pathname用於產生key的文件在使用ftok產生的key的進程運行期間不能被創建和刪除,因為每次文件被創建,它會需要一個新索引結點編號,這就會導致下次使用ftok時獲得了一個不同的key。

3.ipc_perm結構

內核給每個IPC對象維護一個信息結構,其內容跟內核給文件維護的信息類似。

struct ipc_perm  
{  
   uid_t uid;//owner的用戶ID  
   gid_t gid;//owner的組ID  
   uid_t cuid;//creater的用戶ID  
   gid_t cgid;//creater的組ID  
   mode_t mode;//讀寫模式  
   ulong_t seq;//序列號  
   key_t key;//IPC key  
};

4.創建與打開IPC通道

創建或打開一個IPC對象的三個getXXX函數的都需要一個類型為key_t的IPC鍵的key值,並且返回一個整數標識符。該標識符不同於ftok函數的id參數。對於key值,應用程序有兩種選擇:

調用ftok,給它傳遞pathname和id;

指定key為IPC_PRIVATE,這將保證會創建一個新的、唯一的IPC對象;

三個getXXX函數,都有一個oflag參數,他指定IPC對象的讀寫權位,並選擇是創建一個新的IPC對象還是訪問一個已存在的IPC對象,規則如下:

1.key指定為IPC_PRIVATE能保證創建一個唯一的IPC對象。沒有一對id和pathname的組合會導致ftok產生IPC_PRIVATE這個鍵值;

2.設置oflag參數的IPC_CREAT位但不設置它的IPC_EXCL位時,如果指定鍵的IPC對象不存在,那就創建一個新對象,否則返回該對象;

3.設置oflag參數的IPC_CREAT位和它的IPC_EXCL位時,如果所指定鍵的IPC對象不存在,那就創建一個新的對象,否則返回一個EEXIST錯誤,因為該對象已經存在;

4.如果要訪問一個已經存在的IPC,就不能指定IPC_PRIVATE標記,因為這是一個特殊的用於創建IPC對象的鍵值

5.IPC權限

創建一個新的IPC對象時,以下信息就保存該對象的ipc_perm結構中:

1. oflag參數中某些比特會初始化ipc_perm結構的mode成員。

2. cuid和cgid成員分別設置為調用進程的有效用戶ID和有效組ID。這兩個成員合稱為創建者ID。

3. ipc_perm結構的uid和gid成員也分別設置為調用進程的有效用戶ID和有效組ID。這兩個成員合稱為所有者ID。

在創建IPC結構時,除seq以外的所有字段都賦初值。以後,可以調用msgctl、semctl或shmctl修改uid、gid和mode字段。為了改變這些值,調用進程必須是IPC結構的創建者或超級用戶。

需要注意的是:

1.創建者ID永遠不會改變,但是進程可以通過IPC機制中的IPC_SET命令修改所有者ID。三個getXXX沒有使用UNIX的文件創建模式掩碼,IPC對象的權限被設置為指定的值。Posxi IPC非常類似文件,但是System V IPC在權限的存儲上是與文件系統的不同的,它的權限不受文件創建模式掩碼的影響。

2.任意進程要訪問一個IPC對象都需要經歷兩個層級的檢查:一個在IPC對象被打開時(檢查是否指定了未包含在ipc_perm結構中的模式,因為創建的IPC對象的權限是存在於ipc_perm結構中的),一個在IPC對象被使用時(過程類似於PosixIPC的權限檢查)。

6.ipcs和ipcrm程序

由於System V IPC的三種類型不是以文件系統中路徑名標識的,因此使用標准的ls和rm程序無法看到它們,也無法刪除他們。不過實現了這些類型IPC的任何系統都提供兩個特殊的程序:ipcs和ipcrm。ipcs輸出有關System V IPC特性的各種信息,ipcrm則刪除一個System V消息隊列、信號量集或共享儲存區。

7.內核限制

System V IPC的多數實現有內在的內核限制,例如消息隊列的最大數目、每個信號量集的最大信號量數等。

另外還存在一些缺點:

IPC結構是在系統范圍內起作用的,沒有訪問計數。例如,如果創建了一個消息隊列,在該隊列中放入了幾則消息,然後終止,但是該消息隊列及其內容並不被刪除。它們余留在系統中直至:由某個進程調用msgrcv或msgctl讀消息或刪除消息隊列,或某個進程執行ipcrm命令刪除消息隊列;或由正在再啟動的系統刪除消息隊列。

這些IPC結構並不按名字為文件系統所知。因此不能用常規的文件系統函數來存取它們或修改它們的特性。為了支持它們不得不增加了十多個全新的系統調用(msgget、semop、shmat等)。不能用ls命令見到它們,不能用rm命令刪除它們,不能用chmod命令更改它們的存取權。於是,也不得不增加了全新的命令ipcs和ipcrm。

這些IPC不使用文件描述符,所以不能對它們使用多路轉接I/O函數:select和poll。

查看本欄目更多精彩內容:http://www.bianceng.cn/OS/unix/

Copyright © Linux教程網 All Rights Reserved