整理linux共享記憶體

2021-10-06 18:39:44 字數 4805 閱讀 1137

共享記憶體就是允許多個程序訪問同乙個記憶體空間,是在多個程序之間共享和傳遞資料最高效的方式。作業系統將不同程序之間共享記憶體安排為同一段物理記憶體,程序可以將共享記憶體連線到它們自己的位址空間中,如果某個程序修改了共享記憶體中的資料,其它的程序讀到的資料也將會改變。

共享記憶體並未提供鎖機制,也就是說,在某乙個程序對共享記憶體的進行讀寫的時候,不會阻止其它的程序對它的讀寫。如果要對共享記憶體的讀/寫加鎖,可以使用訊號燈。

操作共享記憶體的庫函式

包含在,中

1、shmget庫函式

shmget函式用來獲取或建立共享記憶體,宣告為:

int shmget(key_t key,size_t size,int shm***);

引數key是共享記憶體的鍵值,是乙個整數,typedef unsigned int key_t,是共享記憶體在系統中的編號,不同共享記憶體的編號不能相同,key用十六進製制表示比較好。

引數size是待建立的共享記憶體的大小,以位元組為單位。

引數shm***是共享記憶體的訪問許可權,與檔案的許可權一樣,0666|ipc_creat表示全部使用者對它可讀寫,如果共享記憶體不存在,就建立乙個共享記憶體。

2、shmat庫函式

void *shmat(int shm_id,count void *shm_addr,int shm***);

引數shm_id是由shmget函式返回的共享記憶體標識。

引數shm_addr指定共享記憶體連線到當前程序中的位址位置,通常為空,表示讓系統來選擇共享記憶體的位址。

引數shm_***是一組標誌位,通常為0。 

呼叫成功時返回乙個指向共享記憶體第乙個位元組的指標,如果呼叫失敗返回-1.

3、shmdt函式:

該函式用於將共享記憶體從當前程序中分離,相當於shmat函式的反操作。它的宣告如下:

int shmdt (const void *shmadr);

引數shmaddr是shmat函式返回的位址。

呼叫成功時返回0,失敗時返回-1.

4、shmctl庫函式

刪除共享記憶體,它的宣告如下:

int shmactl(int shm_id,int command,struct shmid_ds *buf);

引數shm_id是shmget函式返回的共享記憶體識別符號。

引數command填ipc_rmid。

引數buf填0。

shmctl是控制共享記憶體的函式,功能很多。

注意,用root建立的共享記憶體,不管建立的許可權是什麼,普通使用者無法刪除

測試:

#include"/root/public.h"

int main()

char *p=0;

p=(char *)shmat(shmid,0,0);

//操作共享記憶體

printf("向共享記憶體寫入前:%s\n",p);

sprintf(p,"寫入本程序的編號是%d\n",getpid());

printf("向共享記憶體寫入後:%s\n",p);

//分離共享記憶體

//shmdt(p);

return 0;

}

./30            

向共享記憶體寫入前:

向共享記憶體寫入後:寫入本程序的編號是31564

[root@izuf6g6gmwubu9o02mecvyz zty]# ./30

向共享記憶體寫入前:寫入本程序的編號是31564

向共享記憶體寫入後:寫入本程序的編號是31565

[root@izuf6g6gmwubu9o02mecvyz zty]# ./30

向共享記憶體寫入前:寫入本程序的編號是31565

向共享記憶體寫入後:寫入本程序的編號是31566

測試分離共享記憶體和刪除共享記憶體。

#include"/root/public.h"

int main()

char *p=0;

p=(char *)shmat(shmid,0,0);

//操作共享記憶體

printf("向共享記憶體寫入前:%s\n",p);

sprintf(p,"寫入本程序的編號是%d\n",getpid());

printf("向共享記憶體寫入後:%s\n",p);

//分離共享記憶體

shmdt(p);

sprintf(p,"寫入本程序的編號是%d\n",getpid());

return 0;

}

向共享記憶體寫入前:寫入本程序的編號是31581

向共享記憶體寫入後:寫入本程序的編號是31596

段錯誤

出現段錯誤,證明分離共享記憶體後,是不能向共享記憶體裡寫入東西。

測試刪除共享記憶體

#include"/root/public.h"

int main()

char *p=0;

p=(char *)shmat(shmid,0,0);

//操作共享記憶體

printf("向共享記憶體寫入前:%s\n",p);

sprintf(p,"寫入本程序的編號是%d\n",getpid());

printf("向共享記憶體寫入後:%s\n",p);

//分離共享記憶體

shmdt(p);

shmctl(shmid,ipc_rmid,0); //刪除共享記憶體

return 0;

}

./30

%[6n享記憶體寫入前:寫入本程序的編號是31600

向共享記憶體寫入後:寫入本程序的編號是31607

[root@izuf6g6gmwubu9o02mecvyz zty]# ./30

向共享記憶體寫入前:

向共享記憶體寫入後:寫入本程序的編號是31608

[root@izuf6g6gmwubu9o02mecvyz zty]# ./30

向共享記憶體寫入前:

向共享記憶體寫入後:寫入本程序的編號是31609

[root@izuf6g6gmwubu9o02mecvyz zty]# ./30

向共享記憶體寫入前:

向共享記憶體寫入後:寫入本程序的編號是31610

可以看出每執行一次程式,都會重新建立新的共享記憶體,由此證明,每次新建的共享記憶體都被刪除了。

共享記憶體的操作命令

用ipcs -m可以檢視系統的共享記憶體,內容有鍵值(key),共享記憶體編號(shmid),建立者(owner),許可權(perms),大小(bytes)。

測試:當我執行缺少刪除共享記憶體**的程式時

會出現:

ipcs -m

------------ 共享記憶體段 --------------

鍵 shmid 擁有者 許可權 位元組 nattch 狀態

0x00005005 262144 root 640 1024 0

這個shimd就是程式中shmget的返回值,即共享記憶體的識別符號,可以列印。如下

#include"/root/public.h"

int main()

printf("shimd=%d\n",shmid);

char *p=0;

p=(char *)shmat(shmid,0,0);

//操作共享記憶體

printf("向共享記憶體寫入前:%s\n",p);

sprintf(p,"寫入本程序的編號是%d\n",getpid());

printf("向共享記憶體寫入後:%s\n",p);

//分離共享記憶體

shmdt(p);

return 0;

}

./30

shimd=262144

向共享記憶體寫入前:寫入本程序的編號是31651

向共享記憶體寫入後:寫入本程序的編號是3166

ipcs -m

------------ 共享記憶體段 --------------

鍵 shmid 擁有者 許可權 位元組 nattch 狀態

0x00005005 262144 root 640 1024 0

用ipcrm -m 共享記憶體編號,可以手工刪除共享記憶體

共享記憶體編號就是shmid,也是shmget的返回值

測試:

ipcs -m

------------ 共享記憶體段 --------------

鍵 shmid 擁有者 許可權 位元組 nattch 狀態

0x00005005 294912 root 640 1024 0

[root@izuf6g6gmwubu9o02mecvyz ~]# ipcrm -m 294912

[root@izuf6g6gmwubu9o02mecvyz ~]# ipcs -m

------------ 共享記憶體段 --------------

鍵 shmid 擁有者 許可權 位元組 nattch 狀態

Linux 共享記憶體

一 概念 共享記憶體是被多個程序共享的一部分物理記憶體,是程序間共享資料的最快的一種方法。二 實現 分為兩個步驟 1 建立共享記憶體。2 對映共享記憶體。1 建立 int shmget key t key,int size,int shm 當key的取值為 ipc private 時,將建立一塊新的...

linux共享記憶體

linux共享記憶體使用 標頭檔案 include 1 建立共享記憶體 int shmget key t key,size t size,int shm 建立成功以後會返回乙個共享記憶體id,建立失敗返回 1。2 獲取共享記憶體 void shmat int shmid,const void shm...

linux 共享記憶體

共享記憶體解決的問題是 任意兩個程序之間的通訊如果是有名管道,是沒有辦法對管道中間的資料獲取讀和寫操作的,只能是兩段的資料,那麼如何對所有的資料進行操作 共享記憶體 共享記憶體也是通過核心來完成 命令 ipcs m p s 共享記憶體的工作機制如下所示 首先linux系統執行的每乙個程式,都是乙個程...