預習訊息佇列,共享記憶體,訊號燈

2021-08-15 19:40:04 字數 3906 閱讀 3702

1、對訊息佇列的操作有下面三種型別:

(1) 開啟或建立訊息佇列。訊息佇列的核心持續性要求每個訊息佇列都在系統範圍內對應唯一的鍵值,所以,要獲得乙個訊息佇列的描述字,只需提供該訊息佇列的鍵值即可。

注:訊息佇列描述字是由在系統範圍內唯一的鍵值生成的,而鍵值可以看作對應系統內的一條路經。

(2)讀寫操作。訊息讀寫操作非常簡單,對開發人員來說,每個訊息都類似如下資料結構:

struct msgbuf

mtype成員代表訊息型別

,從訊息佇列中讀取訊息的乙個重要依據就是訊息的型別

mtext

是訊息內容

,當然長度不一定為

1。因此

,對於傳送訊息來說

,首先預置乙個

msgbuf

緩衝區並寫入訊息型別和內容

,呼叫相應的傳送函式即可

;對讀取訊息來說

,首先分配這樣乙個

msgbuf

緩衝區,

然後把訊息讀入該緩衝區即可。

(3)獲得或設定訊息佇列屬性。訊息佇列的資訊基本上都儲存在訊息佇列頭中,因此可以分配乙個類似於訊息佇列頭的結構,如圖

13-5-2所示,

來返回訊息佇列的屬性

;同樣可以設定該資料結構。

2、訊息佇列api:

(1)ftok函式:用於將檔名轉換成鍵值;

(2)msgget函式:用於建立訊息佇列;

(3)msgrcv函式:用於讀出訊息佇列的資料;

(4)msgsnd函式:用於往訊息佇列寫入資料;

(5)msgctl函式:用於控制訊息佇列。

3、訊息佇列的限制:

每個訊息佇列的容量(所能容納的位元組數

)都有限制

,該值因系統不同而不同。在後面的應用例項中

,輸出了

redhat8.0

的限制另乙個限制是每個訊息佇列所能容納的最大訊息數在

redhad8.0中,

該限制是受訊息佇列容量制約的

:訊息個數要小於訊息佇列的容量

(位元組數)。注

:上述兩個限制是針對每個訊息佇列而言的

,系統對訊息佇列的限制還有系統範圍內的最大訊息佇列個數

,以及整個系統範圍內的最大訊息數。一般來說

,實際開發過程中不會超過這個限制。

mmap()系統呼叫使得程序之間可以通過對映同乙個普通檔案實現共享記憶體。普通檔案被對映到程序位址空間後

,程序可以向訪間普通記憶體一樣對檔案進行訪問

,不必再呼叫

read()

、write(()

等操作注

:實際上

,mmap()

系統呼叫並不是完全為了用於共享記憶體而設計的

,它本身提供了不同於一般對普通檔案的訪問方式

,程序可以像讀寫記憶體一樣對普通檔案的操作。而

posix

或系統v

的共享記憶體

ipc則純粹用於共享目的,當然

mmap()

實現共享記憶體也是其主要應用之一。

5、系統呼叫mmap()用於共享記憶體的兩種方式:

(1)使用普通檔案提供的記憶體對映:適用於任何程序之間;此時,需要開啟或建立乙個檔案,然後再呼叫mmap()。

(2)用特殊檔案提供匿名記憶體對映:適用於具有親緣關係的程序之間

,由於父子程序特殊的親緣關係

,在父程序中先呼叫

mmap(),

然後呼叫

fork()

。那麼在呼叫

fork(之後,

子程序繼承父程序匿名對映後的位址空間

,同樣也繼承

mmap()

返回的位址,這樣

,父子程序就可以通過對映區域進行通訊了。注意

,這裡不是一般的繼承關係

,一般來說

,子程序單獨維護從父程序繼承下來的一些變數,而

mmap()

返回的位址

,卻由父子程序共同維護對於具有親緣關係的程序實現共享記憶體最好的方式應該是採用匿名記憶體對映的方式。此時

,不必指定具體的檔案

,只要設定相應的標誌即可。

6、系統v共享記憶體的原理:

程序間需要共享的資料被放在乙個叫作ipc共享記憶體區域的地方

,所有需要訪問該共享區域的程序都要把該共享區域對映到本程序的位址空間中去。系統

v共享記憶體通過

shmget

獲得或建立乙個

ipc共享記憶體區域

,並返回相應的識別符號。核心在保證

shmget

獲得或建立個共享記憶體區

,初始化該共享記憶體區相應的

ishmikernel

結構注同時

,還將在特殊檔案系統hm中

,建立並開啟乙個同名檔案

,並在記憶體中建立起該檔案的相應

dentry

及inode

結構新開啟的檔案不屬於任何乙個程序

(任何程序都可以訪問該共享記憶體區

)。所有這一切都是通過系統呼叫

shmget

完成的。注

:每乙個共享記憶體區都有乙個控制結構

jstructshmikernel,shmikernel

是共享記憶體區域中非常重要的乙個資料結構

,它是儲存管理和檔案系統結合起來的橋梁。

7、系統v共享記憶體

api(1)shmget函式:用於建立共享記憶體;

(2)shmat函式:用於對映共享記憶體。

shmget()用來獲得共享記憶體區域的

d,如果不存在指定的共享區域就建立相應的區域

shmat()

把共享記憶體區域對映到呼叫程序的位址空間中去,這樣

,程序就可以方便地對共享區或進行訪問操作。

shmdt(

呼叫用來解除程序對共享記憶體區域的對映。

shtetl

實現對共享記憶體區域的控制操作。這裡我們不對這些系統呼叫做具體的介紹

,讀者可參考相應的手冊

,後面的範例中將給出它們的呼叫方法。

8、訊號燈的兩種型別:

(1)一值訊號燈

:最簡單的訊號燈形式

,訊號燈的值只能取0或

1,類似於互斥鎖。 注

:二值訊號燈能夠實現互斥鎖的功能

,但兩者的關注內容不同。訊號燈強調共享資源只要共享資源可用

,其他程序同樣可以修改訊號燈的值

;互斥鎖更強調程序

,占用資源的程序使用完資源後

,必須由程序本身來解鎖。

(2)計算訊號燈

:訊號燈的值可以取任意非負值

(當然受核心本身的約束)。

linu

對訊號燈的支援狀況與訊息佇列一樣,在

redhad8.0

發行版本中支援的是系統

v的訊號燈。因此

,本文將主要介紹系統

v訊號燈及其相應

api。在沒有宣告的情況下

,以下討論中指的都是系統

v訊號燈。

注意:通常所說的系統

v訊號燈指的是計數訊號燈集。

9、對訊號燈的操作無非有下面三個步驟

(1)開啟或建立訊號燈。與訊息佇列的建立及開啟基本相同,不再詳述;

(2)訊號燈值操作。linux可以增加或減小訊號燈的值

,相應於對共享資源的釋放和占有。具體參見後面的

semop

系統呼叫;

(3)獲得或設定訊號燈屬性。系統中的每乙個訊號燈集都對應乙個structsemarray結構

,該結構記錄了訊號燈集的各種資訊

,存在於系統空間。為了設定、獲得該訊號燈集的各種資訊及屬性

,在使用者空間有乙個重要的聯合結構與之對應,即

unionsemen

。10、訊號燈的api:

(1)semget函式用於配置訊號燈;

(2)semop函式用於訊號燈處理;

(3)semctl函式用於控制訊號燈。

訊號燈和共享記憶體機制實現程序通訊

父程序建立子程序互相通訊,父程序從指定檔案中每次讀取一行放入共享記憶體中,子程序將共享記憶體的內容寫入另乙個檔案末尾。由於子程序是無限迴圈,父程序結束前必須殺死子程序,程序結束時會釋放掉等待的訊號量,否則再次執行程式時會直接在建立子程序之前阻塞。include include include inc...

IPC 共享記憶體與訊號燈的基本函式整理

ipc inter process communication,程序間通訊 共享記憶體與訊號燈 include include key t ftok const char pathname,int proj id 常用方法 key t key ftok a if 1 key 使用key開啟或建立ip...

訊號量 訊息佇列 共享記憶體複習

使用訊號量實現父子程序間同步 include include include include include union semun void pv int sem id,int op int main int argc,char argv else waitpid pid,null,0 semct...