標籤:

System V 共享內存 原理 疑惑求解?

系統V共享內存原理

進程間需要共享的數據被放在一個叫做IPC共享內存區域的地方,所有需要訪問該共享區域的進程都要把該共享區域映射到本進程的地址空間中去。系統V共享內存通過shmget獲得或創建一個IPC共享內存區域,並返回相應的標識符。內核在保證shmget獲得或創建一個共享內存區,初始化該共享內存區相應的shmid_kernel結構注同時,還將在特殊文件系統shm中,創建並打開一個同名文件,並在內存中建立起該文件的相應dentry及inode結構,新打開的文件不屬於任何一個進程(任何進程都可以訪問該共享內存區)。所有這一切都是系統調用shmget完成的。

這是網上的解釋,有一些疑惑~~

1、系統V共享內存通過shmget獲得或創建一個IPC共享內存區域, 這個「IPC共享內存區域」 是物理真是存在的么? 那直接往這塊寫不就ok? 為什麼還需要 特殊文件系統shm中,創建並打開一個同名文件

2、 是不是進程真實所共享的內存是這個 特殊文件系統shm中的那個同名文件?


樓主也應該是學C的。。你說一句「直接往這塊寫就OK」。。如何直接寫?指針能濫用嗎?沒經歷過訪問非法內存的錯誤么。所以API沒有提供指針的返回值,也不讓你操縱指針。

共享內存的文件系統問題。共享內存存儲數據是結構化的。在內存里當然都是二進位數據0101。如果其它進程要讀取。,肯定要依據某些規則來解釋這些0101。類似網路裡面有協議的概念,協議就是一組大家認可的規則,關於文件系統也是一個道理。


題主是不懂內核,卻被一群搞過內核的人忽悠住了。

我來為你解答。

IPC共享內存區域是存在的,但 「 物理存在 」 這個概念有點難定義,如果你指的是物理存在是指在物理內存上存在,那我只能說,現代操作系統都是使用 MMU 分為虛擬內存和物理內存的。

然後我要明確告訴你的是,共享內存機制獲得的東西,準確的說不是內存!而是基於 RAM 的文件!這是什麼意思?請繼續往下看。

Linux 有一個系統調用叫 mmap(),這個 mmap() 可以把一個文件映射到進程的地址空間(進程使用的虛擬內存),這樣進程就可以通過讀寫這個進程地址空間來讀寫這個文件。

你可能會覺得奇怪,我明明寫的是內存啊,怎麼會變成寫文件了呢?他們之間是怎麼轉化的呢?

沒錯,你寫的確實是內存,但是你寫的這個內存不是普通的內存,你寫在這個內存上的內容,過段時間後會被內核寫到這個文件上面。而寫文件,其實最後都會變成寫數據到設備里(硬碟、Nand Flash 等)。

了解了 mmap 後,再來談談共享內存的原理。

內核里存在著一個特殊的文件系統,這個文件系統的存儲介質不是別的,正是 RAM。

在 shmget() 調用之後,系統會為你在這個文件系統上創建一個文件,但是這個時候僅僅是創建了這個文件。

然後你就應該調用 shmat() 了,調用 shmat() 之後,內核會使用 mmap 把這個文件映射到你的進程地址空間,這個時候你就能直接讀寫映射後的地址了。

過段時間,內核把你寫的 內容寫到了文件裡面,但是,這個文件的存儲介質是內存,所以他會怎麼做?看明白了吧?

這就是共享內存的原理。

最後回答你的問題:

Q.這個「IPC共享內存區域」 是物理真是存在的么?

A.IPC共享內存區域確實存在,他是一個被映射到你的進程地址空間的文件。其他進程也可以映射,這樣就相當於你們共享了一片內存。

Q. 那直接往這塊寫不就ok?為什麼還需要 特殊文件系統shm中,創建並打開一個同名文件

A. 上面說到,共享內存是被映射到你的進程地址空間的文件,所以不映射是不能直接寫的。

Q. 是不是進程真實所共享的內存是這個 特殊文件系統shm中的那個同名文件?

A. 是


你猜的是對的,其實你也可以不用shmget,我覺得直接open("/dev/shm/xxxx", o_creat)也是可以的。區別在於你要自己保證不同的用戶程序不會用到同名的文件。shmget中,每個幫你保證的。


RTFM

man shmget

man shmdt

man -k shm


推薦閱讀:

Linux下用戶空間的可執行程序代碼段、數據段以及堆棧空間可否安置在hugepage中?
學習linux大致分哪些步驟?
在學習linux下的C編程,想下載一些linux下的程序源碼研究學習,應該去哪獲得?
自我組建殭屍網路的Linux木馬
如何評價Linux deepin 2014 RC版?

TAG:Linux | Linux開發 |