首页 / 操作系统 / Linux / Linux进程间通信之共享内存(system v)
System v的共享内存:共享存储允许两个或多个进程共享一给定的存储区,是同一个计算机中进程间通信的最快方式。和共享内存有关的函数: #include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, size_t size, int shmflg);该函数为获取一个共享内存的标识符,其中key变量可以通过ftok()来获得Size为需要的共享内存大小,shmflg是共享内存标志:IPC_CREAT、IPC_EXCL、;其中IPC_CREAT用于生成一个新的共享内存段,当IPC_CREAT与IPC_EXCL一起使用时,当所要创建的共享内存段已经存在时,将会返回一个EEXIST错误 #include <sys/types.h> #include <sys/shm.h> void *shmat(int shmid, const void *shmaddr, int shmflg);该函数用于将一个共享内存段连接到地址空间中,其中shmid为共享内存段的标识符;shmaddr:(1) 如果shmaddr为0,则此段连接到由内核选择的第一个可用地址上。(2) 如果shmaddr非0,并且没有指定SHM_RND,则此段连接到shmaddr所指定的地址上。(3) 如果shmaddr非0,并且指定了SHM_RMD,则此段连接到(shmaddr-(shmaddr mod SHMLBA))所表示的地址上。SHM_RND命令的意思是:取整。SHMLBA的意思是:低边界地址倍数,它总是2的乘方。该算式是将地址向下取最近1个SHMLBA的倍数。除非只计划在一种硬件上运行应用程序,否则不用指定共享段所连接到的地址。所以一般应指定shmaddr为0,以便由内核选择地址。上面函数的返回值是一个void *指针,所以我们可以自定义共享内存值的数据结构 #include <sys/types.h> #include <sys/shm.h> void *shmat(int shmid, const void *shmaddr, int shmflg);当对共享存储段的操作已经结束时,则调用shmdt脱离连接该共享内存段 #include <sys/ipc.h> #include <sys/shm.h> int shmctl(int shmid, int cmd, struct shmid_ds *buf);该函数用于删除一个共享内存段下面是示例程序send.c函数:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>struct my_shm{int id;char name[20];};int main(int argc, char **argv){ struct my_shm *my_shm; key_t key; int shm_id; char value[20]; int i; key = ftok(".", 22); if(key == -1) key = 1024; shm_id = shmget(key, 2048, IPC_CREAT|0600); if(shm_id == -1) { perror("error shmget
"); return -1; } my_shm = (struct my_shm*)shmat(shm_id, NULL, 0); for(i = 0; i < 10; i++) { (*(my_shm+i)).id = i; memset(((*(my_shm+i)).name),0, sizeof((*(my_shm+i)).name)); sprintf(value,"test shm i is %d", i); memcpy((*(my_shm+i)).name,value, strlen(value)); }system("ipcs -m") sleep(20); shmdt(my_shm); shmctl(shm_id, IPC_RMID, NULL);system("ipcs -m"); return 0;}recv.c函数:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>struct my_shm{int id;char name[20];};int main(int argc, char **argv){ struct my_shm *my_shm; key_t key; int shm_id; char value[20]; int i; key = ftok(".", 22); if(key == -1) key = 1024; shm_id = shmget(key, 2048, IPC_CREAT|0600); if(shm_id == -1) { perror("error shmget
"); return -1; } my_shm = (struct my_shm*)shmat(shm_id, NULL, 0); for(i = 0; i < 10; i++) { printf("id is %d" ,(*(my_shm+i)).id); printf("name is %s
",(*(my_shm+i)).name); } shmdt(my_shm);// shmctl(shm_id, IPC_RMID, NULL); return 0;}