目錄
前言
一、共享內存是什么?
共享內存實現原理
共享內存細節理解
二、接口認識
1.shmget函數——申請共享內存
?2.ftok函數——生成key值
再次理解ftok和shmget
1)key與shmid的區別與聯系
2)再理解key
3)通過指令查看/釋放系統中的ipc資源
3.shmctl函數——控制、釋放共享內存
struct shmid_ds是什么
4.shmat函數和shmdt函數——對共享內存進行關聯和去關聯
三、共享內存的優缺點分析
總結
前言
早在設計Unix時,系統開發者就發現了一個悖論:在某些情況下,系統中的進程既要滿足互相隔離又要彼此協同合作。
由此衍生出了System V IPC等通信方式,在保持進程獨立性的前提下,通過內核中介、權限控制和同步機制實現安全通信。
System V IPC通信機制主要包括:消息隊列/ 信號量/ 共享內存三種通信方式,本文主要討論共享內存的概念原理以及使用方式。
一、共享內存是什么?
先來看看共享內存的概念:
通過讓不同的進程看到同一塊內存的方式,就被稱為“共享內存”
共享內存實現原理
在不破壞進程獨立性的前提下讓兩個進程通信,操作系統通過引入能讓兩個進程都能看到的同一份“資源”實現。對于共享內存,這份資源就是物理內存上的一段內存塊。
以下闡述共享內存的原理。
共享內存細節理解
1)C/C++語言中的malloc等申請空間的函數能用于申請共享內存嗎?
不能,malloc等函數申請的空間只屬于該進程自己,不能被其他進程共享。共享內存機制是專門設計出來用于IPC進程間通信的。
2)共享內存是一種通信方式,想要通信的進程都可以使用。當兩個進程希望進行通信時,可以使用已有的正在被其他進程使用的共享內存通信,也可以額外申請一塊內存用于通信,根據實際需求決定。
3)系統中可能同時存在很多共享內存塊。
二、接口認識
1.shmget函數——申請共享內存
?
2.ftok函數——生成key值
再次理解ftok和shmget
1)key與shmid的區別與聯系
ftok函數返回值是key,shmget的返回值是shmid(共享內存標識符)。key與shmid的關系,有些類似于文件描述符fd與inode的關系,一個是應用進程層面使用的(shmid與fd),另一個是系統內核層面使用的(key與inode)。
2)再理解key
3)通過指令查看/釋放系統中的ipc資源
刪除共享內存指令:
?shmid可以通過上述ipcs指令查看。
3.shmctl函數——控制、釋放共享內存
struct shmid_ds是什么
在shmctl函數的第三個參數中出現了struct shmid_ds結構體,該結構體是操作系統暴露給用戶級的一種數據結構,他與操作系統為方便管理共享內存創建的數據結構再內容上高度類似(系統中的還要更為復雜)。
struct shmid_ds其中記錄了該共享內存的屬性,包括現在有哪些進程正在通過該共享內存通信的信息,以及key值等。
若想獲取共享內存的屬性參數,可以通過創建一個空的struct shmid_ds對象,再將地址傳入shmctl函數中。注意此時的comd參數需傳入IPC_STAT。
struct shmid_ds tmp;
shmctl(shmid,IPC_STAT,&tmp);
4.shmat函數和shmdt函數——對共享內存進行關聯和去關聯
注意:正確的釋放共享內存的流程應該是,先將進程與共享內存去關聯,然后再釋放共享內存
這里附上筆者總結的共享內存創建流程:
在申請共享內存時應做到,誰申請,誰釋放。
三、共享內存的優缺點分析
1.優點
共享內存在所有進程通信間,通信速度是最快的——能減少的拷貝次數。
何以見得共享內存能減少拷貝次數?
假如同樣的代碼和數據,綜合考慮管道和共享內存分別進行通信,在考慮上鍵盤輸入,和顯示器輸出后,共享內存有幾次拷貝數據,管道呢?
由上圖我們可以清楚的觀察到,相比管道,共享內存不用在buffer緩沖區中臨時中轉一下,由此能夠減少一定的數據拷貝。
2.缺點
共享內存在數據通信時,沒有對數據做任何保護——沒有同步、互斥機制。
甚至管道可能出現寫端還未寫完數據,而讀端就來讀取的情況——這時讀端大概率讀到無意義的數據。
比如,管道通信寫端在沒有寫入數據時,讀端會被OS阻塞,反之亦然;
管道在讀端將數據讀取后,寫端再寫會覆蓋已讀的數據。
是否能在不使用信號量的前提下,對共享內存進行保護?
可以給通信的進程雙方添加管道,凡共享內存通信前先借助管道確認對方是否準備完畢。
讀/寫端先不直接訪問共享內存,而是先通過管道通信確認后,再通過共享內存通信。
比如,讀端想要通過共享內存讀取數據之前,先在管道讀端處讀取信號(如一個特定字符)。若未讀取到特定值字符,則由于管道的特性讀端進程會被阻塞,直到寫端發來信號。
總結
本文詳細介紹了System V通信方式中的“共享內存”通信方式。從原理的介紹,到接口的使用,再到最后的優缺點分析,較為系統的剖析共享內存的原理和使用。
雖然共享內存在如今這個萬物互聯的世界越來越不常用,但在某些脫網單機情況下依舊是進程通信的最佳選擇。
希望本文對你有所幫助。
讀完點贊,手留余香~