Linux进程间通信——共享内存

共享内存

特点:最快最简单的IPC

共享内存不用像管道和消息队列进行内核空间向用户空间的转变,它是将一块物理内存通过shmat函数映射到进程的虚拟内存上,进程可以直接操作内存

在这里插入图片描述

/*shm_write.c*/
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>

//       int shmget(key_t key, size_t size, int shmflg);
//       void *shmat(int shmid, const void *shmaddr, int shmflg);
             //      shmid:共享内存id;shaddr:若为NULL则系统自动分配合适空间; shmflg:默认为'0'可读可写                     
//       int shmdt(const void *shmaddr);
//       int shmctl(int shmid, int cmd, struct shmid_ds *buf);
 

int main()
{
       key_t key;
       int shmid;
       char *shmaddr;
       //获取key值
       key = ftok(".",1);
       if(key == -1){
         printf("ftok error\n");
         perror("why:");

       }
       //开辟共享内存
       shmid = shmget(key,1024*4,IPC_CREAT|0666);
      if(shmid == -1){
      
         perror("shmget:");
         exit(-1);
        }
       //内存映射
       shmaddr = shmat(shmid,0,0);//shmid,共享内存id;'0':从第一块共享内存映射;'0':可读可写(默认)
       strcpy(shmaddr,"hello world");
       //解除映射,解除映射后信息存在物理内存之中
       shmdt(shmaddr);
 
       return 0;
}                                  
/*shm_read.c*/
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>

int main()
{

       key_t key;
       int shmid;
       char *shmaddr;

       key = ftok(".",1);
       if(key == -1){
         perror("why:");

       }

        shmid = shmget(key,1024*4,0);
        if(shmid == -1){

         printf("creat shared memory failed\n");
         perror("shm:");
         exit(-1);
        }

       shmaddr =  shmat(shmid,0,0);
       printf("%s\n",shmaddr);
       shmdt(shmaddr);
       //删除共享内存,释放物理内存
       shmctl(shmid,IPC_RMID,0);
       return 0;

}

ps:
1.同一个进程多次进行shmat会出现什么问题?

当首次创建共享内存段时,它不能被任何进程所访问,为了使共享内存区可以被访问,则必须通过shmat函数将其映射到自己的进程空间中。这样进程就与共享内存建立了连接。
这样挂载一个共享内存如果是第一次调用时没有问题的,但是一个进程是可以对同一个共享内存多次shmat进行挂载的,物理内存是指向同一块,如果shmaddr为NULL,则每次返回的线性地址空间都不同,而且指向这块共享内存的引用计数会增加,也就是进程多块线性空间会指向同一块物理地址,这样会一直消耗进程的虚拟内存空间,很有可能会最后导致进程线性空间被使用完,而导致下次shmat或者其他操作失败。
2.查看系统可共享内存大小的指令:
cat /proc/sys/kernel/shmmax <OS分配>
cat /proc/sys/kernel/shmmni <应该是4096>
3.共享内存没有同步机制,一般需要借助其他手段进行同步工作常用的就是信号了,一般是做互斥,因为操作同一片内存,不同进程若同时读写则会造成数据的破坏,这时就需要借助信号限制不同进程的操作

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值