共享内存

匿名 (未验证) 提交于 2019-12-03 00:29:01

共享内存的本质是让两个进程能够看到一块内存区域,共享内存是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,也就是说,进程不再通过执行进入内核的系统调用来传递彼此的数据。

获取共享内存的方式和消息队列类似,下面来介绍一下。

shmget函数:用来创建共享内存。

int shmget(key_t key, size_t size, int shmflg); //key共享内存段名字 //size共享内存的大小 //shmflg权限标志,与mode一样 //返回值:成功返回非负整数,失败返回-1

shmat函数:将共享内存映射到进程地址空间

void *shmat(int shmid, const void* shmaddr, int shmflg); //shmid共享内存标识,shmget的返回值 //shmaddr指定连接的地址,一般为NULL,由操作系统自动加载 //shmflg读写权限,一般给0 //返回值:成功返回共享内存第一个地址,失败返回-1

shmdt函数:将共享内存与进程脱离

int shmdt(const void* shmaddr); //shmaddr:由shmat返回的 地址 //返回值:成功返回0,失败返回-1

shmdt函数:控制共享内存

int shmctl(int shmid, int cmd, struct shmid_ds *buf); //buf指向保存共享内存模式状态和访问权限的数据结构

共享内存的确是IPC最快的通信模式,但是却有一个很大,那就是没有同步互斥机制,为了解决这个问题,我们又引入了一个新的资源,叫做信号量。

通过信号量,我们就可以达到既能通信,也不会发生数据不一致的问题。

下来写一个案例: 共享内存通信完整代码

#include"comm.h" //创建共享内存 int main( void ) {   key_t key = ftok(PATHNAME, PROJ_ID);   if( key < 0){     perror("ftok");     exit(1);   }    int shmid = shmget(key, sizeof(stu_t), IPC_CREAT|IPC_EXCL|0644);   if(shmid < 0){     perror("shmget");     exit(1);   }   printf("cerate ok\n");   return shmid;    printf("create ok\n");  } 

进程client,写数据

#include"comm.h"  static int commShm(int size, int flags) {     key_t key = ftok(PATHNAME, PROJ_ID);     if( key < 0){         perror("ftok");         return -1;     }      int shmid = shmget(key, 36, 0);     if(shmid < 0){     perror("shmget");     exit(1);     }     printf("cerate ok\n");     return shmid; }  int getShm(int size) {     printf("client get\n");     return commShm(size, 0); }   int main() {     int shmid = getShm(36);     stu_t* addr = (stu_t*)shmat(shmid, NULL, 0);     if(NULL == addr){     perror("shmat");     exit(1);     }     sleep(3);     int i = 0;     while(1){     sprintf(addr->name,"ABC%d",i);     i++;     }      shmdt(addr);     sleep(2);     return 0; }

server进程,读数据

#include"comm.h"  static int commShm(int size, int flags) {     key_t key = ftok(PATHNAME, PROJ_ID);     if( key < 0){         perror("ftok");         exit(1);     }      int shmid = shmget(key, 36, flags);     if(shmid < 0){     perror("shmget");     exit(1);     }     printf("cerate ok\n");     return shmid; }  int createShm(int size) {     printf("certe\n");     return commShm(size, 0); }  int destroyShm(int shmid) {     int del = shmctl(shmid, IPC_RMID, NULL);     if(del < 0)     {         perror("shmctl");         exit(19);     }     return 0; }  int main() {     int shmid = createShm(36);      stu_t* addr = (stu_t*)shmat(shmid, NULL, 0);     if(NULL == addr)     {     perror("shmat");     return -1;     }     int i = 3;     while(i--){     printf("come to while\n");     sleep(1);     printf("%s\n",addr->name);     }     shmdt(addr);     sleep(2);     printf("Program is over\n");     //destroyShm(shmid);     return 0; }

这个代码没有去解决同步互斥的问题,但是通过信号量,是可以解决这个问题的。

文章来源: 共享内存
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!