【Linux】进程间通信--共享内存

ipcs / ipcrm 介绍:

        ipcs 可以查看消息队列、共享内存、信号量的使用情况,使用 ipcrm 可以进行删除操作。

一、共享内存原理

        进程可同时访问同一块内存,对进程没有要求。<sys/shm.h>

        共享内存为多个进程之间共享和传递数据提供了一种有效的方式。共享内存是先在物理

内存上申请一块空间,多个进程可以将其映射到自己的虚拟地址空间中。所有进程都可以访

问共享内存中的地址,就好像它们是由 malloc 分配的一样。如果某个进程向共享内存写入了

数据,所做的改动将立刻被可以访问同一段共享内存的任何其他进程看到。由于它并未提供

同步机制,所以我们通常需要用其他的机制来同步对共享内存的访问。

二、参数介绍

1.shmget():创建或者获取共享内存

        成功返回共享内存的 ID, 失败返回-1。

        int shmget(key_t key, size_t size, int shmflg);

key:共享内存段唯一标识符,不同进程使用相同的key值可以获取到同一个共享内存。

size:共享内存的大小,必须是整数,如果是获取共享内存段,可填0。

shmflg: 用于控制函数的行为。

        IPC_CREAR:如果key不存在,则创建新段。

        IPC_EXCL: 与IPC_CREAT结合使用,如果已存在,会报错。

        权限控制:需要指定权限0600。

2.shmat():将申请的共享内存的物理内存映射到当前进程的虚拟地址空间上。

        成功返回共享内存首地址,失败返回NULL。

        将一个已存在的共享内存段附加一个内存块到进程的地址空间中,一旦附加成功,进程就可以像访问普通内存一样访问共享区域。

        void *shmat(int shmid, const void *_Nullable shmaddr, int shmflg);

shmid:共享内存段id号,由shmget返回获取。

shmaddr:指定共享内存要附加到地址空间的哪个位置。

        NULL:一般让内核自动选择映射的虚拟地址空间。

        非NULL:如果shmget没有设置标志,会定位一个精确位置,如果该地址不可用,函数调用失败。

shmflg:标志位,决定函数附加功能。

        0:默认权限,根据创建时的权限进行操作。

        SHM_RDONLY: 只读访问共享内存,如果写操作,会段错误。

        SHM_EXEC: 允许在共享内存段上执行代码。

3.shmdt():断开当前进程的shmaddr指向的共享内存映射。

        成功返回0,失败返回-1。

        断开附加内存块,不允许内存块上的内容影响共享内存。

        int shmdt(const void *shmaddr);

shmaddr: 附加的内存块的地址。

4.shmctl():控制共享内存。

        成功返回0,失败返回-1。

        int shmctl(int shmid, int op, struct shmid_ds *buf);

op: IPC_RMID。

三、代码练习

示例代码 1:进程 a 向共享内存中写入数据,进程 b 从共享内存中读取数据并显示。

a.c 的代码:

b.c的代码:

运行结果:

示例代码 2:进程 a 从键盘循环获取数据并拷贝到共享内存中,进程 b 从共享内存中获

取并打印数据。要求进程 a 输入一次,进程 b 输出一次,进程 a 不输入,进程 b 也不输出。

        由于共享内存并未提供同步机制,所以我们通常需要用其他的机制来同步对共享内存的访问。

下面代码将使用有名管道来同步。

a.c的代码:

b.c的代码:

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值