请选择 进入手机版 | 继续访问电脑版
快捷导航
2 91

Linux进程间通信-共享内存

小亮 于 2017-12-16 16:57 发表在 [技术分享] [复制链接]
1、什么是内存共享?内存共享就是允许两个不相关的进程访问同一逻辑内存。
2、内存共享的方式
  (1)、shm方式是将每个进程的共享内存与实际物理存储器进行映射,对实际物理内存影响较大;

  (2)、mmap是将文件与进程地址空间进行映射,对实际物理内存影响较小;

注:两者区别就不在这细说了,可自行查阅资料。
3、共享内存相关函数
  (1)、int shmget( key_t key, size_t size, int shmflg)
  该函数用来创建共享内存!
  第一个参数,进程需要提供一个参数key(非0整数),为共享内存段命名,shmget函数执行成功后会返回一个与key相关的共享内存标识符(非负整       数),用于后续共享内存函数。执行失败则返回-1;
  第二个参数,大于0的整数:新建共享内存大小,以字节为单位;
                       等于0:只获取共享内存时指定为0;
  第三个参数,shmflg等于0:取共享内存大小,以字节为单位;
                      IPC_CREAT:如果内核中不存在与键值与key相等的共享内存,则新建一个共享内存;如果存在则返回此共享内存的标识符;
                      IPC_CREAT|IPC_EXCL:如果内核中不存在与键值与key相等的共享内存,则新建一个共享内存;如果存在则会报错;
  (2)、void *shmat(int shm_id, const void *shm_addr, int shmflg)
  该函数用来启动对该共享内存的访问,并把共享内存连接到当前进程的地址空间!
  第一个参数,shm_id:是由shmget函数返回的共享内存标识;
  第二个参数,shm_addr:指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址位置,通常为空,表示让系统   来选择共享内存的地址;
  第三个参数,shm_flg是一组标识位,通常为0;
  调用成功时返回一个指向共享内存第一个字节的指针,如果调用失败返回-1;
  (3)、int shmdt(const void *shmaddr)
  该函数用于将共享内存从当前进程中分离!
  参数shmaddr是shmat函数返回的地址指针,调用成功返回0,调用失败返回-1;

  (4)、int shmctl( int shm_id, int command, struct shmid_ds *buf)
  该函数用来对共享内存的控制!
  第一个参数,shm_id:是shmget函数返回的共享内存标识符;
  第二个参数,command:要采取的操作;
                      IPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构复制到buf中;
                      IPC_SET:改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode复制到共享内存的shmid_ds结构内;
                      IPC_RMID:删除共享内存段;
  第三个参数,buf:是一个结构指针,它指向共享内存模式和访问权限结构;

  调用成功返回0,失败返回-1;
4、两个进程间利用共享内存通信
两个进程main.c和test.c,分别对共享区域进行写和读,写读同一时刻只能执行一个动作。
main.c//定义结构体struct share_buff数据域为write_flag写标识,textbuff[SIZE]用于存放共享内存中的数据大小2048
  1. shmid = shmget(12315,SIZE,IPC_CREAT);//创建共享内存
  2.         if(shmid == -1)
  3.         {
  4.     printf("shmget creat error!\r\n");
  5.     exit(EXIT_FAILURE);
  6.         }        
  7.         shm = shmat(shmid,0,0);//将共享内存连接到当前进程的地址空间
  8.         if(shm == (void *)-1)
  9.         {
  10.     printf("shmat error!\r\n");
  11.     exit(EXIT_FAILURE);
  12.         }
  13.         shm_buff = (struct share_buff* )shm;//设置共享内存地址为struct share_buff变量shm_buff的首地址
  14.         while(1)
  15.         {
  16.     if(shm_buff->write_flag)
  17.     {
  18.         printf("waitting writting ....\r\n");
  19.     }
  20.     fgets(buff,SIZE,stdin);//接收输入数据写入共享内存
  21.     strncpy(shm_buff->textbuff,buff,SIZE);//
  22.     shm_buff->write_flag = 1;//标识可读
  23.     if(strncmp(buff,"end",3)==0)//判断输入end程序结束
  24.     break;
  25.         }
复制代码


test.c
  1. shmid = shmget(12315,SIZE,IPC_CREAT);//创建共享内存
  2.         if(shmid ==-1)
  3.         {
  4.     printf("shmget error!\r\n");
  5.     exit(EXIT_FAILURE);
  6.         }
  7. shm = shmat(shmid,0,0);//将共享内存连接到当前进程的地址空间
  8.         if(shm == (void *)-1)
  9.         {
  10.     printf("shmat error!\r\n");
  11.     exit(EXIT_FAILURE);
  12.         }
  13.         shm_buff = (struct share_buff *)shm;//设置共享内存地址为struct share_buff变量shm_buff的首地址
  14.         while(1)
  15.         {
  16.     if(shm_buff->write_flag)//判断标识位是否可读
  17.     {
  18.         printf("the buff:%s\r\n",shm_buff->textbuff);//读取共享内存数据并打印
  19.         shm_buff->write_flag = 0;//标识位置0
  20.     }else{
  21.     sleep(2);
  22.     }
  23.         }
复制代码
gcc进行编译,先运行main向共享内存写入数据后再运行test结果如下:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
Connecting & Messaging from Any.

共 2 个关于本帖的回复 最后回复于 2017-12-16 20:47

李腾杰 中级会员 发表于 2017-12-16 17:31:13 | 显示全部楼层
good job
Connecting & Messaging from Any.
举报 使用道具
chinmel 版主 发表于 2017-12-16 20:47:58 from Mobile | 显示全部楼层
可以。我们可以进一步设想一下: 在这个公共的共享内存中,实现一个内存分配管理器,进而实现共享内存的动态分配(shm malloc),如何?3天的时间,研究一下。然后我们看服务器代码
Connecting & Messaging from Any.
举报 使用道具
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

推荐板块

精彩推荐

热门排行

明星用户

手机版|小黑屋|AnyMSG ( ©AnyMSG 2009 - 2017 · ICP备16009991号 )

GMT+8, 2019-4-25 22:51