1. 程式人生 > >Linux環境程序間通訊(五) 共享記憶體(下)

Linux環境程序間通訊(五) 共享記憶體(下)

系統呼叫mmap()通過對映一個普通檔案實現共享記憶體。系統V則是通過對映特殊檔案系統shm中的檔案實現程序間的共享記憶體通訊。也就是說,每個共享記憶體區域對應特殊檔案系統shm中的一個檔案(這是通過shmid_kernel結構聯絡起來的),後面還將闡述。

1、系統V共享記憶體原理

程序間需要共享的資料被放在一個叫做IPC共享記憶體區域的地方,所有需要訪問該共享區域的程序都要把該共享區域對映到本程序的地址空間中去。系統V共享記憶體通過shmget獲得或建立一個IPC共享記憶體區域,並返回相應的識別符號。核心在保證shmget獲得或建立一個共享記憶體區,初始化該共享記憶體區相應的shmid_kernel結構注同時,還將在特殊檔案系統shm中,建立並開啟一個同名檔案,並在記憶體中建立起該檔案的相應dentry及inode結構,新開啟的檔案不屬於任何一個程序(任何程序都可以訪問該共享記憶體區)。所有這一切都是系統呼叫shmget完成的。

注:每一個共享記憶體區都有一個控制結構struct shmid_kernel,shmid_kernel是共享記憶體區域中非常重要的一個數據結構,它是儲存管理和檔案系統結合起來的橋樑,定義如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 struct shmid_kernel /* private to the kernel */ {   struct kern_ipc_perm    shm_perm; struct file *       shm_file;
int         id; unsigned long       shm_nattch; unsigned long       shm_segsz; time_t          shm_atim; time_t          shm_dtim; time_t          shm_ctim; pid_t           shm_cprid; pid_t           shm_lprid; };

該結構中最重要的一個域應該是shm_file,它儲存了將被對映檔案的地址。每個共享記憶體區物件都對應特殊檔案系統shm中的一個檔案,一般情況下,特殊檔案系統shm中的檔案是不能用read()、write()等方法訪問的,當採取共享記憶體的方式把其中的檔案對映到程序地址空間後,可直接採用訪問記憶體的方式對其訪問。

這裡我們採用[1]中的圖表給出與系統V共享記憶體相關資料結構:

正如訊息佇列和訊號燈一樣,核心通過資料結構struct ipc_ids shm_ids維護系統中的所有共享記憶體區域。上圖中的shm_ids.entries變數指向一個ipc_id結構陣列,而每個ipc_id結構陣列中有個指向kern_ipc_perm結構的指標。到這裡讀者應該很熟悉了,對於系統V共享記憶體區來說,kern_ipc_perm的宿主是shmid_kernel結構,shmid_kernel是用來描述一個共享記憶體區域的,這樣核心就能夠控制系統中所有的共享區域。同時,在shmid_kernel結構的file型別指標shm_file指向檔案系統shm中相應的檔案,這樣,共享記憶體區域就與shm檔案系統中的檔案對應起來。

在建立了一個共享記憶體區域後,還要將它對映到程序地址空間,系統呼叫shmat()完成此項功能。由於在呼叫shmget()時,已經建立了檔案系統shm中的一個同名檔案與共享記憶體區域相對應,因此,呼叫shmat()的過程相當於對映檔案系統shm中的同名檔案過程,原理與mmap()大同小異。

2、系統V共享記憶體API

對於系統V共享記憶體,主要有以下幾個API:shmget()、shmat()、shmdt()及shmctl()。

1 2 #include <sys/ipc.h> #include <sys/shm.h>

shmget()用來獲得共享記憶體區域的ID,如果不存在指定的共享區域就建立相應的區域。shmat()把共享記憶體區域對映到呼叫程序的地址空間中去,這樣,程序就可以方便地對共享區域進行訪問操作。shmdt()呼叫用來解除程序對共享記憶體區域的對映。shmctl實現對共享記憶體區域的控制操作。這裡我們不對這些系統呼叫作具體的介紹,讀者可參考相應的手冊頁面,後面的範例中將給出它們的呼叫方法。

注:shmget的內部實現包含了許多重要的系統V共享記憶體機制;shmat在把共享記憶體區域對映到程序空間時,並不真正改變程序的頁表。當程序第一次訪問記憶體對映區域訪問時,會因為沒有物理頁表的分配而導致一個缺頁異常,然後核心再根據相應的儲存管理機制為共享記憶體對映區域分配相應的頁表。

3、系統V共享記憶體限制

在/proc/sys/kernel/目錄下,記錄著系統V共享記憶體的一下限制,如一個共享記憶體區的最大位元組數shmmax,系統範圍內最大共享記憶體區識別符號數shmmni等,可以手工對其調整,但不推薦這樣做。

在[2]中,給出了這些限制的測試方法,不再贅述。

4、系統V共享記憶體範例

本部分將給出系統V共享記憶體API的使用方法,並對比分析系統V共享記憶體機制與mmap()對映普通檔案實現共享記憶體之間的差異,首先給出兩個程序通過系統V共享記憶體通訊的範例:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

相關推薦

Linux環境程序通訊: 共享記憶體(轉)

轉自http://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index2.html, 作者:鄭彥興系統呼叫mmap()通過對映一個普通檔案實現共享記憶體。系統V則是通過對映特殊檔案系統shm中的檔案實現程序間的共享記憶體通訊。也就是說,每個共享記憶體區域對

Linux環境程序通訊: 共享記憶體(轉)

轉自http://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index1.html, 作者:鄭彥興採用共享記憶體通訊的一個顯而易見的好處是效率高,因為程序可以直接讀寫記憶體,而不需要任何資料的拷貝。對於像管道和訊息佇列等通訊方式,則需要在內 核和使用者空間

Linux環境程序通訊 共享記憶體

系統呼叫mmap()通過對映一個普通檔案實現共享記憶體。系統V則是通過對映特殊檔案系統shm中的檔案實現程序間的共享記憶體通訊。也就是說,每個共享記憶體區域對應特殊檔案系統shm中的一個檔案(這是通過shmid_kernel結構聯絡起來的),後面還將闡述。 1、系統V共

Linux環境程序通訊: 訊號(轉)

訊號本質訊號是在軟體層次上對中斷機制的一種模擬,在原理上,一個程序收到一個訊號與處理器收到一箇中斷請求可以說是一樣的。訊號是非同步的,一個程序不必通過任何操作來等待訊號的到達,事實上,程序也不知道訊號到底什麼時候到達。訊號是程序間通訊機制中唯一的非同步通訊機制,可以看作是非同步通知,通知接收訊號的程序有哪些事

Linux 環境程序通訊 套介面(轉)

轉自https://www.ibm.com/developerworks/cn/linux/l-ipc/part6/, 作者:鄭彥興一個套介面可以看作是程序間通訊的端點(endpoint),每個套介面的名字都是唯一的(唯一的含義是不言而喻的),其他程序可以發現、連線並且 與之通訊。通訊域用來說明套介面通訊的協

Linux環境程序通訊 訊息佇列(轉)

轉自http://www.ibm.com/developerworks/cn/linux/l-ipc/part3/, 作者:鄭彥興訊息佇列(也叫做報文佇列)能夠克服早期unix通訊機制的一些缺點。作為早期unix通訊機制之一的訊號能夠傳送的資訊量有限,後來雖然 POSIX 1003.1b在訊號的實時性方面作了

Linux環境程序通訊 訊號燈(轉)

轉自http://www.ibm.com/developerworks/cn/linux/l-ipc/part4/, 作者:鄭彥興訊號燈與其他程序間通訊方式不大相同,它主要提供對程序間共享資源訪問控制機制。相當於記憶體中的標誌,程序可以根據它判定是否能夠訪問某些共享資源,同時,程序也可以修改該標誌。除了用於訪

Linux環境程序通訊: 訊號(轉)

從訊號傳送到訊號處理函式的執行完畢對於一個完整的訊號生命週期(從訊號傳送到相應的處理函式執行完畢)來說,可以分為三個重要的階段,這三個階段由四個重要事件來刻畫:訊號誕生;訊號在程序中註冊完畢;訊號在程序中的登出完畢;訊號處理函式執行完畢。相鄰兩個事件的時間間隔構成訊號生命週期的一個階段。 下面闡述四個事件的實

Linux環境程序通訊 管道及有名管道(轉)

管道是Linux支援的最初Unix IPC形式之一,具有以下特點:管道是半雙工的,資料只能向一個方向流動;需要雙方通訊時,需要建立起兩個管道;只能用於父子程序或者兄弟程序之間(具有親緣關係的程序);單獨構成一種獨立的檔案系統:管道對於管道兩端的程序而言,就是一個檔案,但它不是普通的檔案,它不屬於某種檔案系統,

Linux環境程序通訊 訊號燈

一、訊號燈概述訊號燈與其他程序間通訊方式不大相同,它主要提供對程序間共享資源訪問控制機制。相當於記憶體中的標誌,程序可以根據它判定是否能夠訪問某些共享資源,同時,程序也可以修改該標誌。除了用於訪問控制外,還可用於程序同步。訊號燈有以下兩種型別:二值訊號燈:最簡單的訊號燈形式,

Linux環境程序通訊——共享記憶體

原文連結     原文連結:http://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index1.html 概述     Android系統中大量使用了mmap實現的共享記憶體,所以這裡需要介紹一下LInux程序間通訊

Linux環境程序通訊共享記憶體

共享記憶體簡介 共享記憶體允許兩個或多個程序共享一給定的儲存區。因為資料不需要在客戶程序和伺服器程序之間複製,所以這是最快的一種IPC。共享記憶體的方式有兩種:mmap()系統呼叫和系統V共享記憶體。 mmap()系統呼叫 mmap()系統呼叫使得程序之間通過對映同一個普通

Android native程序通訊例項-binder結合共享記憶體

  在android原始碼的驅動目錄下,一般會有共享記憶體的相關實現原始碼,目錄是:kernel\drivers\staging\android\ashmem.c。但是本篇文章不是講解android共享記憶體的功能實現原理,而是講怎麼運用它。   1.    在linux中,不同程序間擁有自己獨

Linux程序通訊匿名管道命名管道共享記憶體,訊息佇列,訊號量

目錄 程序間通訊的介紹 管道 匿名管道 原理: 程式碼實現 匿名管道特性 實現管道符 |  命名管道 命名管道特性 程式碼實現 管道讀寫規則 作業系統中ipc的相關命令 共享記憶體(重點) 生命週期: 程式碼實現 程式碼實現獲

Linux程序通訊IPC之訊號量詳解與測試用例

學習環境centos6.5 Linux核心2.6 程序間通訊概述 1. 程序通訊機制 一般情況下,系統中執行著大量的程序,而每個程序之間並不是相互獨立的,有些程序之間經常需要互相傳遞訊息。但是每個程序在系統中都有自己的地址空間,作業系統通過頁表

Linux程序通訊IPC之訊息佇列詳解及測試用例

學習環境 Centos6.5 Linux 核心 2.6 什麼是訊息佇列? 訊息佇列是SystemV版本中三種程序通訊機制之一,另外兩種是訊號量和共享儲存段。訊息佇列提供了程序間傳送資料塊的方法,而且每個資料塊都有一個型別標識。訊息佇列是基於訊息的,而管

Linux程序通訊IPC共享記憶體詳解與測試用例

學習環境centos6.5 Linux核心2.6 什麼是共享記憶體 共享記憶體允許兩個或更多程序訪問同一塊記憶體。當一個程序改變了這塊記憶體中的內容的的時候,其他程序都會察覺到這個更改。 效率: 因為所有程序共享同一塊記憶體,共享記憶體在各種程序

boost程序通訊常用開發一篇全訊息佇列,共享記憶體,訊號

本文概要:         敏捷開發大家想必知道而且評價甚高,縮短開發週期,提高開發質量。將大工程獨立為不同的小app開發,整個開發過程,程式可用可測,所以提高了整體的質量。基於這種開發模式和開發理念,程序間通訊必然是童鞋們必掌握技能之一了,而boost庫是眾多庫中平臺支援

Linux程序通訊之管道通訊詳解

        在學習程序的時候,我們瞭解到了程序的獨立性:程序之間是相互獨立的,每個程序有自己的虛擬地址空間,並且虛擬地址空間通過頁表的對映,對映到屬於自己的實體記憶體上。並且各個程序之間互相不影響,執行自己的程式碼。    

Linux關於程序通訊共享記憶體

共享記憶體概念 共享記憶體允許兩個不相關的程序去訪問同一部分邏輯記憶體 如果需要在兩個執行中的程序之間傳輸資料,共享記憶體將是一種效率極高的解決方案 共享記憶體是由IPC為一個程序建立的一個特殊的地址範圍,它將出現在程序的地址空間中。 其他程序可以把同一段共享記憶體段“連