作業系統之共享儲存區詳解 Linux shm

2021-10-05 06:57:51 字數 3479 閱讀 3491

在學習作業系統的時候,老師講到程序間通訊,今天在這裡介紹一下程序通訊中的共享儲存區通訊

共享記憶體分為兩種,以下是維基百科上的說法:

硬體術語

共享記憶體指在多處理器的計算機系統中,可以被不同**處理器訪問的大容量記憶體。由於多個cpu需要快速訪問儲存器,這樣就要對儲存器進行快取。由於其他處理器可能也要訪問,任一快取資料更新後,共享記憶體就需要立即更新,否則不同處理器可能用到不同的資料(參見快取一致和記憶體一致)。

共享記憶體的類似方案有分布記憶體、分布共享記憶體,用以解決同類問題。

軟體術語

在軟體中,術語共享記憶體指可被多個程序訪問的記憶體,乙個程序是一段程式的單個執行例項。在這種情況下,共享記憶體被用作程序間的通訊。

我今天在這裡介紹shm共享記憶體。使用共享記憶體進行程序通訊時需要用到四個函式:shmget(),shmat(),shmdt(),shmctl()。這四個函式的使用需要宣告sys/shm.h標頭檔案

#include

①shmget()

get函式原型:

int

shmget

(key_t key,size_t size,

int shm***)

;

shmget()用來獲得共享記憶體區域的id(如果不存在該共享記憶體區域則建立乙個新的共享記憶體區域)

引數解釋

key_t key 共享記憶體識別符號,兩個不相關的程序之間我們可以自定義乙個key來使用,若為父子程序的話,該識別符號可為ipc_private(需要在父子程序都可見的地方呼叫(即在建立子程序之前),否則不能實現記憶體的共享)。

size_t size 共享記憶體size。

int shmflag 許可權標誌,記憶體模式(mode)

引用自

shm***主要和一些標誌有關。其中有效的包括ipc_creat和ipc_excl,它們的功能與open()的o_creat和o_excl相當。

ipc_creat 如果共享記憶體不存在,則建立乙個共享記憶體,否則開啟操作。

ipc_excl 只有在共享記憶體不存在的時候,新的共享記憶體才建立,否則就產生錯誤。

如果單獨使用ipc_creat,shmget()函式要麼返回乙個已經存在的共享記憶體的操作符,要麼返回乙個新建的共享記憶體的識別符號。

如果將ipc_creat和ipc_excl標誌一起使用,shmget()將返回乙個新建的共享記憶體的識別符號;如果該共享記憶體已存在,或者返回-1。

ipc_exel標誌本身並沒有太大的意義,但是和ipc_creat標誌一起使用可以用來保證所得的物件是新建的,而不是開啟已有的物件。

這個可以用,但最好不要用:

對於使用者的讀取和寫入許可指定shm_r和shm_w;

(shm_r>3)和(shm_w>3)是一組讀取和寫入許可,而(shm_r>6)和(shm_w>6)是全域性讀取和寫入許可。

推薦使用這個:

可以使用0666|ipc_creat,來作為shm***的值。
成功返回共享記憶體的識別符號;不成功返回-1,errno儲存錯誤原因。

einval 引數size小於shmmin或大於shmmax。

eexist 預建立key所致的共享記憶體,但已經存在。

eidrm 引數key所致的共享記憶體已經刪除。

enospc 超過了系統允許建立的共享記憶體的最大值(shmall )。

enoent 引數key所指的共享記憶體不存在,引數shm***也未設ipc_creat位。

eacces 沒有許可權。

enomem 核心記憶體不足。

②shmat()

attach

函式原型:

void

*shmat

(int shm_id,

const

void

*shm_addr int shm***)

;

shmat()用來啟動對這個共享記憶體區域的訪問,連線到使用者的虛位址空間。

引數解釋

int shm_id 共享程序區域的id

void *shm_addr

int shm*** 記憶體的操作模式。如果是shm_rdonly的話,就是唯讀模式。其它的是讀寫模式。成功時,這個函式返回共享記憶體的起始位址。失敗時返回-1。

③shmdt()

detach

函式原型:

int

shmdt

(const

void

*shm_addr)

;

shmdt()用來刪除本程序對這塊記憶體的使用,shmdt()與shmat()相反,是用來禁止本程序訪問一塊共享記憶體的函式。

引數解釋

void *shm_addr 共享記憶體區域的起始位址

成功返回0

失敗返回-1

④shmctl()

control

函式原型:

int

shmctl

(int shm_id,

int command,

struct shmid_ds *buf)

;

shmctl() 控制對此共享記憶體的使用

引數解釋

int shm_id 共享記憶體區域的id

int command(cmd) 控制命令

ipc_stat//獲得共享記憶體的狀態

ipc_set//改變共享記憶體的狀態

ipc_rmid//刪除共享記憶體

struct shmid_ds *buf 為乙個結構體指標,指向共享記憶體mode和訪問許可權的結構。

struct shmid_ds 

;

上**:

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

#define shmkey 75

int shmid,p1,p2;

int*addr;

void

client()

}void

server()

while

(*addr)

;shmctl

(shmid,ipc_rmid,0)

;}intmain()

else

}wait(0

);wait(0

);return0;

}

上列**中,在呼叫shmat()時,需要用到強制型別轉換,因為shmat的函式原型是void*型別,而我們需要得到int型的返回值,需要加上((int *)shmat(shmid,0,0));

作業系統之儲存器管理

儲存器的層次如下圖 上圖中,暫存器和主儲存器稱為可執行儲存器。快取記憶體的作用是緩和cpu與記憶體之間的速度差異,主要由硬體實現。磁碟快取的出現是由於記憶體容量不夠,需要引入磁碟,然而磁碟的i o速度遠低於主存的訪問速度,為了緩和兩者之間在速度上的差異,設定了磁碟快取。磁碟快取與快取記憶體不同,它本...

作業系統之磁碟儲存器

首先了解下這三個名詞的概念 磁碟儲存器管理的主要任務和要求 有效地利用儲存空間。即採取合理的檔案分配方式,為檔案分配必要的儲存空間。同時減少磁碟碎片。提高磁碟i o速度。例如磁碟高速緩衝 disk cache 廉價冗餘磁碟陣列 redundant array of inexpensive disk,...

作業系統之虛擬儲存器

1.常規儲存器管理方式的特徵和區域性性原理 常規儲存器管理方式的特徵 一次性。要求將作業全部裝入記憶體才能執行,當程式大於記憶體時,作業無法執行。駐留性。裝入記憶體中用的作業一直駐留記憶體,直到執行結束 處於等待狀態的程序也占用記憶體 區域性性原理 時間侷限性。如果程式中的某條指令一旦執行,則不久以...