天天看點

《UNIX網絡程式設計 卷2:程序間通信(第2版)》——2.3 建立與打開IPC通道

本節書摘來自異步社群《unix網絡程式設計 卷2:程序間通信(第2版)》一書中的第2章,第2.3節,作者:【美】w. richard stevens著,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視

mq_open、sem_open和shm_open這三個建立或打開一個ipc對象的函數,它們的名為oflag的第二個參數指定怎樣打開所請求的對象。這與标準open函數的第二個參數類似。圖2-3給出了可組合構成該參數的各種常值。

《UNIX網絡程式設計 卷2:程式間通信(第2版)》——2.3 建立與打開IPC通道

前3行指定怎樣打開對象:隻讀、隻寫或讀寫。消息隊列能以其中任何一種模式打開,信号量的打開不指定任何模式(任意信号量操作,都需要讀寫通路權),共享記憶體區對象則不能以隻寫模式打開。

圖2-3中餘下4行标志是可選的。

o_creat 若不存在則建立由函數第一個參數所指定名字的消息隊列、信号量或共享記憶體區對象(同時檢查o_excl标志,我們不久将要說明)。

建立一個新的消息隊列、信号量或共享記憶體區對象時,至少需要另外一個稱為mode的參數。該參數指定權限位,它是由圖2-4中所示常值按位或形成的。

《UNIX網絡程式設計 卷2:程式間通信(第2版)》——2.3 建立與打開IPC通道

這些常值定義在頭檔案中。所指定的權限位受目前程序的檔案模式建立掩碼(file mode creation mask)修正,而該掩碼可通過調用umask函數(apue第83~85頁②)或使用shell的umask指令來設定。

跟新建立的檔案一樣,當建立一個新的消息隊列、信号量或共享記憶體區對象時,其使用者id被置為目前程序的有效使用者id。信号量或共享記憶體區對象的組id被置為目前程序的有效組id或某個系統預設組id。新消息隊列對象的組id則被置為目前程序的有效組id(apue第77~78頁③詳細讨論了使用者id群組id。)

這三種posix ipc類型在設定組id上存在的差異多少有點奇怪。由open新建立的檔案的組id或者是目前程序的有效組id,或者是該檔案所在目錄的組id,但是ipc函數不能假定系統為ipc對象建立了一個在檔案系統中的路徑名。

o_excl 如果該标志和o_creat一起指定,那麼ipc函數隻在所指定名字的消息隊列、信号量或共享記憶體區對象不存在時才建立新的對象。如果該對象已經存在,而且指定了o_creat|o_excl,那麼傳回一個eexist錯誤。

考慮到其他程序的存在,檢查所指定名字的消息隊列、信号量或共享記憶體區對象的存在與否和建立它(如果它不存在)這兩步必須是原子的(atomic)。我們将在3.4節看到适用于systemv ipc的兩個類似标志。

o_nonblock 該标志使得一個消息隊列在隊列為空時的讀或隊列填滿時的寫不被阻塞。我們将在5.4節随mq_receive和mq_send這兩個函數詳細讨論該标志。 - o_trunc 如果以讀寫模式打開了一個已存在的共享記憶體區對象,那麼該标志将使得該對象的長度被截成0。

圖2-5展示了打開一個ipc對象的真正邏輯流程。我們将在2.4節通過通路權限的測試說明該圖。圖2-6是展示圖2-5中邏輯的另一種形式。

《UNIX網絡程式設計 卷2:程式間通信(第2版)》——2.3 建立與打開IPC通道

注意圖2-6指定了o_creat标志但沒有指定o_excl标志的中間那行,我們無法得到一個訓示以判别是建立了一個新對象,還是在引用一個已存在的對象。