共享內存是進程間通信中最簡單的方式之一。共享內存允許兩個或更多進程訪問同一塊內存,就如同 malloc() 函數向不同進程返回了指向同一個物理內存區域的指針。當一個進程改變了這塊地址中的內容的時候,其它進程都會察覺到這個更改。
參考資料:
共享內存特點
-
共享內存是進程間共享數據最快的方法
一個進程向共享內存寫入數據,共享這個內存區域的所有進程就可以立即看到其中的內容。
-
使用共享內存需要注意的是多進程之間對一個給定存儲區訪問的互斥
若一個進程正在向共享區寫數據,則在它操作完成之前,其他的進程不應當去讀、寫這些數據。
示例代碼如下
memShareWrite.c
//
// IPC--共享內存(寫數據)
// Created by 盧鵬 on 2017/8/31.
//
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
// 共享內存大小
#define BUFFSIZE 1024
int main(int argc, char *argv[]) {
// 共享內存的shmid
int shmid;
// 共享內存的key
key_t key;
char *shmadd;
char *msg;
// 創建共享內存的key
if ((key = ftok("./", 2015)) == -1) {
perror("ftok error");
}
// 創建共享內存
if ((shmid = shmget(key, BUFFSIZE, IPC_CREAT|0666)) < 0) {
perror("shmget error.");
exit(-1);
}
printf("Create shared-memory success, with shmid: %d\n", shmid);
// 映射
if ((shmadd = shmat(shmid, NULL, 0)) < 0) {
perror("shmat error.");
exit(-1);
}
// 拷貝共享數據到共享內存
printf("copy data to shared-memory\n");
bzero(shmadd, BUFFSIZE);
msg = "hello, yj.";
strcpy(shmadd, msg);
printf("copy data to shared-memory success, with msg: %s\n", msg);
}
memShareRead.c
//
// IPC--共享內存(讀數據)
// Created by 盧鵬 on 2017/8/31.
//
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFSIZE 1024
int main(int args, char *argv[]) {
int shmid;
int ret;
key_t key;
char *shmadd;
// 創建key值
if ((key = ftok("./", 2015)) == -1) {
perror("ftok error.");
}
// 查看系統共享內存
printf("start-ipcs------------------------------------------\n");
system("ipcs -m");
printf("end-ipcs--------------------------------------------\n");
// 打開共享內存
if ((shmid = shmget(key, BUFFSIZE, IPC_CREAT|0666)) < 0) {
perror("shmget error.");
exit(-1);
}
printf("Open shared-memory success, with shmid: %d\n", shmid);
// 映射
if ((shmadd = shmat(shmid, NULL, 0)) < 0) {
perror("shmat error.");
exit(-1);
}
// 讀取共享內存中的數據
printf("read data from shared-memory\n");
printf("%s\n", shmadd);
// 分離共享內存和當前進程
if ((ret = shmdt(shmadd)) < 0) {
perror("shmdt error.");
exit(1);
} else {
printf("Delete shared-memory\n");
}
// 刪除共享內存
shmctl(shmid, IPC_RMID, NULL);
// 查看系統共享內存
printf("start-ipcs------------------------------------------\n");
system("ipcs -m");
printf("end-ipcs--------------------------------------------\n");
return 0;
}
運行結果
➜ gcc memShareWrite.c -o w
➜ gcc memShareRead.c -o w
➜ chmod +x w
➜ chmod +x r
➜
➜
➜ ./w
Create shared-memory success, with shmid: 327680
copy data to shared-memory
copy data to shared-memory success, with msg: hello, yj.
➜
➜
➜ ./r
start-ipcs------------------------------------------
IPC status from <running system> as of Fri Sep 1 11:03:18 CST 2017
T ID KEY MODE OWNER GROUP
Shared Memory:
m 327680 0xdf041eec --rw-rw-rw- lpe234 staff
end-ipcs--------------------------------------------
Open shared-memory success, with shmid: 327680
read data from shared-memory
hello, yj.
Delete shared-memory
start-ipcs------------------------------------------
IPC status from <running system> as of Fri Sep 1 11:03:18 CST 2017
T ID KEY MODE OWNER GROUP
Shared Memory:
end-ipcs--------------------------------------------
最後
但在實際編程中,應該使用信號量,或通過傳遞消息(使用管道或IPC消息),或生成信號的方法來提供讀寫之間的更有效的同步機制。