共享内存允许两个或更多进程访问同一块内存,不同进程之间共享的内存通常为计算机中的同一段物理内存,就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针。当一个进程改变了这块地址中的内容的时候,其它进程都会察觉到这个更改。进程可以将同一段物理内存连接到他们自己的地址空间中(通过虚拟地址映射),所有的进程都可以访问共享内存中的地址。
共享内存的优缺点:
原文链接:https://blog.csdn.net/d_guco/article/details/53524854
1.共享内存号称是最快的进程间通信方式。
2.共享内存适用于大数据量的传输,读取不等待写入,需要设置同步,可以用信号量来实现对共享内存同步访问控制。可以通过管道发送同步信号。管道适合传输小数据量。
3.通过名字知道它是基于内存的,所以他只能在同一主机上使用,如果我们要做分布式应用或者跨物理机通信,那么socket就是我们唯一的选择了。
-
向共享内存中存放数据时,需在共享内存映射之后再存放数据,否则存放不成功
-
存放数据时若出现段错误时,则可能是因为代码中出现了野指针
-
若两个进程中开辟的共享内存空间不一致则报错:shmget: Invalid argument
情景:创建两个进程,在 A 进程中创建一个共享内存,并向其写入数据(结构体形式进行数据传输 ),通过 B 进程从共享内存中读取数据
A写进程:
#include#include #include #include #include #include #include #define BUFSZ 100 struct Mem{ int type ; char data[BUFSZ]; }; int main(int argc, char *argv[]) { //struct Mem mem1; int shmid; int ret; key_t key; struct Mem *shmadd; //创建key值 key = ftok("/dev/ppp", 2021); if(key == -1) { perror("ftok"); } //创建共享内存 shmid = shmget(key, BUFSZ*sizeof(char)+sizeof(int), IPC_CREAT|0666); if(shmid < 0) { perror("shmget"); exit(-1); } //映射 shmadd = (struct Mem *)shmat(shmid, NULL, 0); if(shmadd < 0) { perror("shmat"); _exit(-1); } // 共享内存清空 memset(shmadd, 0, sizeof(shmadd)); //拷贝数据至共享内存区 printf("copy data to shared-memoryn"); //bzero(mem1.data, BUFSZ); // 共享内存清空 (*shmadd).type = 1; strcpy((*shmadd).data, "how are you, lhn"); //拷贝数据至共享内存区 //printf("copy data to shared-memoryn"); //strcpy(shmadd, "how are you, lhn"); printf("type = [%d]n", (*shmadd).type); printf("data = [%s]n", (*shmadd).data); return 0; }
B读进程:
#include#include #include #include #include #include #include #define BUFSZ 100 typedef struct MemA{ int type; char data[BUFSZ]; }MemA; int main(int argc, char *argv[]) { int shmid; int ret; key_t key; MemA *shmadd; //创建key值 key = ftok("/dev/ppp", 2021); if(key == -1) { perror("ftok"); } system("ipcs -m"); //查看共享内存 //打开共享内存 shmid = shmget(key, BUFSZ +4, IPC_CREAT|0666); if(shmid < 0) { printf("error"); perror("shmget"); exit(-1); } //映射 shmadd = (MemA *)shmat(shmid, NULL, 0); if(shmadd < 0) { perror("shmat"); exit(-1); } //读共享内存区数据 printf("type = [%d]n", (*shmadd).type); printf("data = [%s]n", (*shmadd).data); //分离共享内存和当前进程 ret = shmdt(shmadd); if(ret < 0) { perror("shmdt"); exit(1); } else { printf("deleted shared-memoryn"); } //删除共享内存 shmctl(shmid, IPC_RMID, NULL); system("ipcs -m"); //查看共享内存 return 0; }
提示:
代码中所用到的函数详情可参考链接: https://cloud.tencent.com/developer/article/1527533.
总结
1.实现数据以结构体形式进行进程之间通信。
2.代码未提供同步机制



