一,共享內存
內核管理一片物理內存,允許不同的進程同時映射,多個進程可以映射同一塊內存,被多個進程同時映射的物理內存,即共享內存。
映射物理內存叫掛接,用完以后解除映射叫脫接。
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: