一,共享記憶體
核心管理一片實體記憶體,允許不同的程序同時映射,多個程序可以映射同一塊記憶體,被多個程序同時映射的實體記憶體,即共享記憶體。
映射實體記憶體叫挂接,用完以後解除映射叫脫接。
1,共享記憶體的特點:
優點:是最快的IPC。
缺點:要程式設計者自己實作對共享記憶體互斥通路。如何實作?
2,程式設計模型:具體函數的用法可以用man手冊檢視(強力推薦)
程序A: writeshm.c
1) 獲得key, ftok()
2) 使用key來建立一個共享記憶體 shmget()
3) 映射共享記憶體(得到虛拟位址), shmat()
4) 使用共享記憶體, 往共享記憶體中寫入資料
5) 解除映射 shmdt()
6) 如果共享記憶體不再使用,可以使用shmctl()銷毀共享記憶體
程序B: readshm.c
1) 獲得key, ftok()
2) 使用key來獲得一個共享記憶體 shmget()
3) 映射共享記憶體(得到虛拟位址), shmat()
4) 使用共享記憶體, 讀取共享記憶體中的資料
5) 解除映射 shmdt()
3,執行個體
程序A:
// writeshm.c
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
int main()
{
// 生成一個key
key_t key = ftok("./", 66);
// 建立共享記憶體,傳回一個id
int shmid = shmget(key, 8, IPC_CREAT|0666|IPC_EXCL);
if(-1 == shmid)
{
perror("shmget failed");
exit(1);
}
// 映射共享記憶體,得到虛拟位址
void *p = shmat(shmid, 0, 0);
if((void*)-1 == p)
{
perror("shmat failed");
exit(2);
}
// 寫共享記憶體
int *pp = p;
*pp = 0x12345678;
*(pp + 1) = 0xffffffff;
// 解除映射
if(-1 == shmdt(p))
{
perror("shmdt failed");
exit(3);
}
printf("解除映射成功,點選回車銷毀共享記憶體\n");
getchar();
// 銷毀共享記憶體
if(-1 == shmctl(shmid, IPC_RMID, NULL))
{
perror("shmctl failed");
exit(4);
}
return 0;
}
程序B:
// readshm.c
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
int main()
{
// 生成一個key
key_t key = ftok("./", 66);
// 擷取共享記憶體,傳回一個id
int shmid = shmget(key, 0, 0);
if(-1 == shmid)
{
perror("shmget failed");
exit(1);
}
// 映射共享記憶體,得到虛拟位址
void *p = shmat(shmid, 0, 0);
if((void*)-1 == p)
{
perror("shmat failed");
exit(2);
}
// 讀共享記憶體
int x = *(int *)p;
int y = *((int *)p + 1);
printf("從共享記憶體中都取了:0x%x 和 0x%x \n", x, y);
// 解除映射
if(-1 == shmdt(p))
{
perror("shmdt failed");
exit(3);
}
return 0;
}
運作結果:
writeshma:
readshma: