Linux SystemV(共享内存(*)、消息队列、信号量)

个人主页仍有未知等待探索-CSDN博客

专题分栏: Linux

目录

​编辑

一、共享内存

1、原理

理解:

2、操作+具体理解

1.概括

2.创建共享内存

共享内存的生命周期?

key是什么?

进程怎么知道,共享内存是否存在?

shmget的返回值?

其他进程是怎么知道用户设置的key?

3.共享内存挂接到地址空间

数据安全(*)

4.内存空间的管理

二、消息队列

1、原理

2、接口

发送消息和接收消息

生命周期

三、信号量

1、五个概念

2、对于信号量的理论的理解

信号量对共享内存进行访问的过程:

信号量的分类:

信号量能用一个全局的变量进行替代吗?

数据安全:

3、信号量的操作

1.创建

2.管理

3.操作

四、共同点

os是如何吧对应的共享内存,消息队列,信号量统一管理起来的?


一、共享内存

1、原理

理解:

  • 上述的操作都是os完成的。
  • os必须提供对应步骤的系统调用。
  • 共享空间可以在系统中存在很多份,供不同的进程同时进行通信。
  • os要对共享内存进行管理。先描述再组织。共享内存,不是简单的一段内存空间,也要有描述并管理共享内存的数据结构和匹配的算法!
  • 共享内存 = 内存空间(数据)+ 共享内存的属性。
  • 共享内存不提供对共享内存的任何保护机制

  • 共享内存生命周期随内核,文件生命周期随进程

2、操作+具体理解

1.概括

2.创建共享内存

#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg); --- 创建共享空间
// 函数的返回值是shmid是共享内存在用户层面的标识符,是一个整数。
// key:用户设置的标识符,标识共享内存,要有唯一性。
// size:共享内存的大小,建议设置成4096的整数倍
// shmflg:共享内存的权限
// IPC_CREAT:如果要创建的共享内存不存在,创建;如果存在,获取共享内存并返回。 --- 用来获取
// IPC_EXCL:单独使用没有意义。
// IPC_CREAT | IPC_EXCL:如果要创建的共享内存不存在,创建;如果就存在,出错返回。 --- 用来创建 

#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id); --- 形成key
// pathname:创建共享内存的路径
// proj_id:项目号,自定义设置,没有要求

创建的时候需要加上共享内存的权限,类似于:IPC_CREAT | IPC_EXCL | 0666。

共享内存的生命周期?

共享内存的生命周期随系统,而不是进程。

key是什么?

标识共享内存的编号。

进程怎么知道,共享内存是否存在?

如果是os创建key值得话,本地进程知道,其他进程获取不到。所以要自己设置key值,key值也要具有唯一性。

通过查找key值存不存在就知道对应的共享内存是否存在。

shmget的返回值?

返回用户层面的共享内存标识符(shmid)。

  • shmid用于对共享内存进行操作。
  • key用于查找共享内存是否存在。
其他进程是怎么知道用户设置的key?

通过同样的规则,利用ftok系统调用。

3.共享内存挂接到地址空间

#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg); --- 挂接
int shmdt(const void *shmaddr); --- 去挂接
 

数据安全(*)

共享内存不提供对共享内存的任何保护机制 --- 会造成数据不一致问题。

共享内存是所有进程IPC速度最快的,因为共享内存大大减少了数据的拷贝次数!

共享内存的大小是4096的整数倍。

4.内存空间的管理

#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
  • cmd是对内存空间管理的各种选项:

  • buf是存储的内存空间的属性。如果是要获取共享内存状态,buf是输出型参数;如果是要修改共享内存状态,buf是修改完成的共享内存状态,然后底层会把buf拷贝到内核中。

二、消息队列

1、原理

一个进程,向另一个进程发送有类型的数据块的方式。

2、接口

接口都是类似于共享内存的。

发送消息和接收消息

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);

const void*msgp:发送的消息数据块的地址。
struct msgbuf:消息队列数据块。
struct msgbuf
{
    long mtype;
    char mtext[1];
}

生命周期

 消息队列的生命周期随系统。

三、信号量

1、五个概念

  1. 共享资源:多个执行流(cpu)能看到同一份资源。
  2. 临界资源:被保护起来的资源。(保护的方式,同步和互斥)
  3. 互斥:在任何时刻,只能有一个进程在访问共享资源。

  4. 资源:只要是资源就要被程序员访问的。--- 资源被访问,就是通过代码访问(朴素)代码 = 访问共享资源的代码(临界资源) + 不访问共享资源的代码(非临界资源)。

  5. 所谓的对共享资源的保护,本质是对访问共享资源的代码进行保护。(这里的共享资源就是临界区)

2、对于信号量的理论的理解

  • 信号量是用来保护临界资源的。
  • 信号量的本质是一个计数器。                            

    类似于电影院买票:

    电影院:共享资源(临界资源)

    买票:申请信号量。--- 如果某场电影没有票了,就意味着,信号量为0,不能被申请。

    票数:信号量的初始值。

  • 申请信号量本质:就是对公共资源的一种预定机制。

信号量对共享内存进行访问的过程:

1、申请信号量。计数器减减操作。

2、访问共享内存。

3、释放信号量。计数器加加操作。

信号量的分类:

多元 和 二元。

二元信号量(类比超级vip):只有 1 or 0 --- 互斥。对共享资源进行整体使用。

多元信号量:网吧中的电脑,对于电脑,有很多台,其信号量大于2。

信号量能用一个全局的变量进行替代吗?

信号量不能用一个全局变量gcount当计数器。

1、全局变量不能被所有进程看到。

2、gcount不是原子。

数据安全:

IPC信号量和共享内存,消息队列一样,也必须先让不同的进程看到同一个“计数器”!--- 意味着信号量也是一个公共资源!! --- 保护临界资源安全的前提是信号量是安全的。

-- -> 安全的 -> P操作

++ -> 安全的 -> V操作

PV --- 安全 --- 原子性

3、信号量的操作

  • 允许用户一次申请多个信号量。

  • 信号量集 --- 用数组来维护。

1.创建

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);

这些参数和共享内存的一样的含义。

2.管理

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, ...);

3.操作

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop(int semid, struct sembuf *sops, size_t nsops);

sem_op == 1,就是加加操作。
sem_op == -1,就是减减操作。

sops是个结构体,包含下列的属性。

四、共同点

1、划分为同一个标准:system V。

2、XXXget,XXXctl,生命周期随系统的。

3、都有XXXid_ds的struct结构,第一个属性都是struct ipc_perm;

os是如何吧对应的共享内存,消息队列,信号量统一管理起来的?

 谢谢大家!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仍有未知等待探索

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值