Linux学习笔记之共享内存

共享内存对象:(SHM)

操作框架:

key值==》申请对象==》挂载对象==》读写对象==》卸载对象 ==》删除对象
shmget() shmat() 内存读写 shmdt() shmctl()

1、申请对象
#include <sys/ipc.h>
#include <sys/shm.h>

int shmget(key_t key, size_t size, int shmflg);
功能:该函数使用公共key值向内核提出共享内存使用申请;
参数: key 唯一键值
size 要申请的共享内存大小
shmflg 申请方式和权限,第一次 IPC_CREAT
判断是否存在用 IPC_EXCL;
返回值:成功 返回一个有效的shmid表示消息队列对象id
失败 -1;

2、挂载对象(映射对象)

void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:该函数可以将已经申请成功的共享内存挂载到本地进程的
私有空间地址上。
参数: shmid 共享内存id
shmaddr 当前进程的可读写、空闲、同等大小 的内存挂载地址;
NULL 表示由系统自动查找合适区域并挂载;
shmflg 挂载到本地的内存读写权限;
返回值:成功 返回已经挂载成功的本地内存
失败 NULL

3、读写共享内存:所有的io读写方式都可以,对于共享内存的读写可以
借鉴malloc堆区内存的读写方式;

练习:
使用共享内存完成 父子进程间的 数字 字符串 结构体 三种
不同数据信息的进程间通信;

注意:共享内存挂载成功后,操作的内存在本地,目标内存在共享区域
但是内存的所有操作一定要借鉴堆区内存。

4、卸载共享内存 ( 断开映射 )

int shmdt(const void *shmaddr);
功能:该函数用于卸载之前已经挂载的共享内存;
参数:shmaddr 要断开的地址
返回值:成功 0
失败 -1;
注意:使用完毕尽量将指针归零 shmaddr = NULL;

5、删除共享内存
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
功能:该函数用于修改共享内存的属性,可以用于删除共享内存;
参数:shmid 共享内存id
cmd IPC_RMID 表示删除共享内存对象
buf NULL 表示属性不做调整;
返回值:成功 0
失败 -1;

//共享内存写内存
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>

struct  shmbuf
{
      int a;
      char b;
};
int main()
{

      key_t key;
      
      if((key=ftok(".",'m'))<0)
      {
            perror("ftok error\n");
            return -1;
      }
      
      int shmid;
      struct shmbuf *shm;
      if((shmid=shmget(key,512,IPC_CREAT|IPC_EXCL|0664))<0)
      {
           if(errno!=EEXIST)
           {
                 perror("shmget error\n");
                 return -1;
           }
           else
           {
                 shmid=shmget(key,512,0664);
           }
      }
      if((shm=shmat(shmid,NULL,0))!=NULL)
      {
           printf("shm=%p\n",shm);
      }
      //写内存
      shm->a=10;
      shm->b='q';
      
      if(shmdt(shm)<0)
      {
           perror("shmdt error\n");
           return -1;
      }
      
      system("ipcs -m");
      return 0;
}
//共享内存读内存
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>

struct  shmbuf
{
      int a;
      char b;
};
int main()
{

      key_t key;
      
      if((key=ftok(".",'m'))<0)
      {
            perror("ftok error\n");
            return -1;
      }
      
      int shmid;
      struct shmbuf *shm;
      if((shmid=shmget(key,512,IPC_CREAT|IPC_EXCL|0664))<0)
      {
           if(errno!=EEXIST)
           {
                 perror("shmget error\n");
                 return -1;
           }
           else
           {
                 shmid=shmget(key,512,0664);
           }
      }
      if((shm=shmat(shmid,NULL,0))!=NULL)
      {
           printf("shm=%p\n",shm);
      }
      //读内存
      printf("a=%d b=%c\n",shm->a,shm->b);
      
      if(shmdt(shm)<0)
      {
           perror("shmdt error\n");
           return -1;
      }
      
      shmctl(shmid,IPC_RMID,NULL);
      
      system("ipcs -m");
      return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值