共享記憶體就是允許多個程序訪問同乙個記憶體空間,是在多個程序之間共享和傳遞資料最高效的方式。作業系統將不同程序之間共享記憶體安排為同一段物理記憶體,程序可以將共享記憶體連線到它們自己的位址空間中,如果某個程序修改了共享記憶體中的資料,其它的程序讀到的資料也將會改變。
共享記憶體並未提供鎖機制,也就是說,在某乙個程序對共享記憶體的進行讀寫的時候,不會阻止其它的程序對它的讀寫。如果要對共享記憶體的讀/寫加鎖,可以使用訊號燈。
操作共享記憶體的庫函式
包含在,中
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系統執行的每乙個程式,都是乙個程...