2013-07-06 55 views
2

Linux內核如何在不同進程之間實現共享內存機制?Linux內核如何在2個進程間實現共享內存

爲了進一步詳細描述,每個過程都有自己地址空間。例如,進程A中的0x1000的地址與進程B中的地址0x1000相比是不同的位置。

那麼內核如何確保不同進程之間共享一塊內存,具有不同的地址空間?

在此先感謝。

回答

4

間通信機制

過程與彼此和與內核通信以協調他們的活動。 Linux支持許多進程間通信(IPC)機制。信號和管道是其中的兩個,但Linux也支持System V IPC機制,它們是在Unix TM發行版中命名的,它們最初出現在這些機制中。

信號

信號是由Unix TM系統中使用的最古老的進程間通信方法之一。它們用於向一個或多個進程發送異步事件。信號可以通過鍵盤中斷或錯誤條件產生,例如嘗試訪問虛擬內存中不存在的位置的進程。信號也被shell使用來向其子進程發送作業控制命令。 有一組定義的信號,內核可以生成或者可以由系統中的其他進程生成,但前提是它們具有正確的權限。您可以使用kill命令列出系統的一組信號(kill -l)。

常見的Linux炮彈都允許重定向。例如

$ ls | pr | lpr

將來自ls命令的輸出列出目錄的文件,並將它們分頁爲pr命令的標準輸入。最後,pr命令的標準輸出被輸入到lpr命令的標準輸入中,該命令在默認打印機上打印結果。然後管道是單向字節流,將一個進程的標準輸出連接到另一個進程的標準輸入。這兩個進程都沒有意識到這種重定向,並且行爲正常。它是在這些過程之間建立這些臨時管道的外殼。

enter image description here

在Linux中,一個管使用兩個文件中的數據結構來實現其中兩個點在相同的臨時VFS的inode本身指向在存儲器內的物理頁面。圖顯示每個文件數據結構都包含指向不同文件操作例程向量的指針;一個用於寫入管道,另一個用於讀取管道。

套接字

  • 消息隊列:消息隊列允許一個或多個進程來寫消息,這將通過一個或多個讀出過程讀出。 Linux維護一個消息隊列列表,即msgque向量;其中的每個元素指向完整描述消息隊列的msqid_ds數據結構。當創建消息隊列時,會從系統內存中分配一個新的msqid_ds數據結構,並將其插入向量中。 enter image description here
  • 系統V IPC機制:Linux支持三種類型的第一次出現在的Unix TM系統V(1983)的進程間通信機制。這些是消息隊列,信號量和共享內存。這些System V IPC機制都共享通用的身份驗證方法。進程只能通過系統調用將唯一的引用標識符傳遞給內核來訪問這些資源。使用訪問權限檢查對這些System V IPC對象的訪問,就像檢查對文件的訪問一樣。 System V IPC對象的訪問權限由對象的創建者通過系統調用設置。對象的引用標識符被每個機制用作資源表的索引。這不是一個簡單的索引,但需要一些操作來生成索引。
  • 信號量:信號量最簡單的形式是內存中的一個位置,其值可以通過多個進程測試和設置。就每個過程而言,測試和設置操作是不可中斷的或原子的;一旦開始,什麼都不能阻止它。測試和設置操作的結果是信號量的當前值和設置值的增加,可以是正值或負值。根據測試和設置操作的結果,一個進程可能需要休眠,直到另一個進程更改了semphore的值。信號量可用於實現關鍵代碼區域,即一次只能執行一個進程的關鍵代碼區域。

假設您有許多合作進程從單個數據文件讀取記錄並將記錄寫入單個數據文件。你會希望該文件訪問得到嚴格的協調。您可以使用初始值爲1的信號量,並在文件操作代碼周圍放置兩個信號量操作,第一個用於測試和減小信號量的值,第二個用於測試並遞增信號量。訪問文件的第一個過程會嘗試減小信號量的值,並且它會成功,現在信號量的值爲0.現在可以繼續使用數據文件,但如果現在另一個希望使用它的進程嘗試減少信號量的值會因爲結果爲-1而失敗。該過程將被暫停,直到第一個過程完成數據文件。當第一個進程結束數據文件時,它將增加信號量的值,使其再次爲1。現在等待的過程可以被喚醒,而這次增加信號量的嘗試將會成功。 enter image description here

  • 共享內存:共享內存允許一個或多個進程經由出現在所有它們的虛擬地址空間的存儲器進行通信。虛擬內存的頁面由每個共享進程的頁表中的頁表條目引用。它不必位於所有進程的虛擬內存中的相同地址。與所有System V IPC對象一樣,通過密鑰和訪問權限檢查來控制對共享內存區域的訪問。一旦共享內存,就不會檢查進程如何使用它。他們必須依靠其他機制(例如System V信號量)來同步對內存的訪問。 enter image description here

tldp.org引用。

+4

-1問題是關於共享內存的實現。您提供了可用IPC機制的*概述*,其中大多數不相關,但沒有真正回答這個問題。此外,「啓發」並不是直接從其他來源複製的內容的正確英文單詞。你應該清楚地表明你的帖子是一個引用和[引用確切的來源網址](http://www.tldp.org/LDP/tlk/ipc/ipc.html)。 –

3

看看Beej's definitive guide to IPC on Linux

包含示例代碼詳細解釋的

  1. 叉()
  2. 信號
  3. 管道
  4. FIFO
  5. 文件鎖定
  6. 消息隊列
  7. 信號燈
  8. 共享內存段
  9. 內存映射文件
  10. Unix套接字

和一堆引用的約IPC幾乎所有在Linux上。