linux进程通信:共享内存

进程之间的通信方式有很多种,本文详细地介绍一种:共享内存。

1.定义

这里的共享内存是指两个或者多个进程,能够共同访问一段物理内存,每个进程对内存内部的数据操作,都会影响其他进程。例如A进程,在把内存段1的值定义为5,过了1s,B进程把内存段1的值改为了10,那么之后A再来访问时,只能取到10,它的5被别的进程修改了。就像黑板和笔记本一样,黑板是共享的,大家都可以擦除别人写的东西,然后写上自己的,而笔记本就不是共享的,只能由一个人使用。
这里我们可能会想到,那么A进程的参数被B进程改了,A又不知道,那岂不是会造成很多错误。是的,所以提到共享,我们还需要研究同步,进程锁也应运而生。

2.linux下c语言创建共享内存

1)创建共享内存——shmget()函数

它的原型为:

int shmget(key_t key, size_t size, int shmflg);
参数含义
key把一个已存在的路径名和一个整数标识符转换成IPC键值,这里的key是键值,它能有效地为共享内存段命名
size指定共享内存容量
shmflg权限标志,它可以做很多事情,例如shmget(key_t key, size_t size, IPC_CRET)表示如果共享内存不存在时,需要分配一个共享内存
返回值shmget成功时,返回一个与key相关的共享内存标识符,调用失败时返回-1

程序想使用共享内存?
程序用shmget+key生成共享内存标识符
程序利用共享内存标识符间接访问共享内存

这里有人会问了,这个shmget到底是生成共享内存标识符还是创建共享内存,这个函数是在有共享内存时,就不创建了,只根据key返回共享内存标识符。没有共享内存时,则创建共享内存,并返回标识符。

2)共享内存连接至进程地址空间——shmat()函数
它的原型为:

void *shmat(int shm_id, const void *shm_addr, int shmflg);
参数含义
shm_id共享内存标识符
shm_addr指定共享内存连接当前进程内存位置,通常为空,让系统自主设置
shmflg权限标志,通常为0
返回值shmat成功时,返回一个指向共享内存首地址的指针,调用失败时返回-1

3)共享内存从进程分离——shmctl()函数
它的原型为:

int shmdt(const void *shmaddr);
参数含义
shmaddr调用函数shmat时,返回的指向共享内存首地址的指针。

4)控制共享内存——shmctl()函数
它的原型为:

int shmctl(int shm_id, int command, struct shmid_ds *buf);
参数含义
shm_id共享内存标识符
command操作符:IPC_STAT:共享内存的当前关联值覆盖shmid_ds的值。IPC_SET:在权限允许的情况下,将shmid_ds的值赋值给共享内存当前关联值。IPC_RMID:删除共享内存段
buf它指向共享内存模式和访问权限的结构

shmid_ds结构

struct shmid_ds
{
    uid_t shm_perm.uid;
    uid_t shm_perm.gid;
    mode_t shm_perm.mode;
};

整体流程

这里设AAA为我们的一个结构体,我们的共享空间是为我们的结构体AAA服务的,因此共享空间的尺寸为sizeof(struct AAA)

1)创建共享内存

shmid = shmget((key_t)8888, sizeof(struct AAA), IPC_CREAT);

2)将共享内存连接到当前地址空间

shm = shmat(shmid, 0, 0);

3)利用共享空间首地址
我们得到的共享空间首地址指针为shm,这个shm可能不是我们想要的指针类型,因此我们需要把它强制转换成我们的结构体指针

shared = (struct AAA*)shm; 

为结构体中的变量a赋值5,这里可以看到结构体指针和我们定义的结构体变量差不多,不同在于:
结构体指针需要用指向运算符(->)
结构体变量需要用成员运算符(.)。

shared->a = 5;

4)使用完毕,共享内存分离

shmdt(shm)

5)删除共享内存

shmctl(shmid, IPC_RMID, 0)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值