system V 本地通信(共享内存 /消息队列 / 信号量)

一、共享内存

1、原理

之前的管道方式是基于文件系统来实现的进程间通信,儿共享内存是在内存中开辟一段空间供进程通信,本质不同。

2、细节

(1)上述操作都是操作系统做的。

(2)操作系统一定会提供1,2步的系统调用供进程使用。

(3)共享内存存在多份,供不同对进程使用

(4)所以共享内存先描述再组织,struct shm

(5)共享内存 = 共享空间(数据)+ 共享内存属性

3、实现

(1)函数介绍

int shmget(key_t key, size_t size, int shmflg) 创建共享内存

key:用户设置,具有唯一性,让进程找到同一份共享内存。

size:内存大小。

shmflg:标记位

IPC_CREAT:如果共享内存不存在就创建,存在就获取后返回。(获取已经创建的共享内存User)

IPC_EXCL:单独使用无意义。

IPC_CREAT | IPC_EXCL:如果共享内存不存在就创建,存在就出错返回。(创建一个新的共享内存Creater)

返回值:共享内存标识符shmid

key_t ftok(const char* pathname, int proj_id) 获取key

pathname:共享内存路径

proj_id:设置id用于创建唯一key

int shmctl(int shmid, int cmd, struct shmid_ds* buf) 控制共享内存

cmd:IPC_RNID命令用于删除共享内存。

ipcs -m 查看共享内存

ipcrm -m shmid 删除共享内存

(2)对比key,shmid

key是用户创建,内核使用,用来区分shm唯一性,用户无法使用。

shmid是共享内存标识符,用来用户级内存管理的id值。

所以删除共享内存用的是shmid

(3)实现

(4)挂接与取消挂接共享内存

上述代码只是申请了共享内存,我们需要挂接共享内存进行使用。

void* shmat(int shmid, const void* shmaddr, int shmflg) 挂接共享内存

shmaddr:挂接位置

shmflg:共享内存权限

失败返回nullptr,成功返回起始地址,相当于malloc返回值。

int shmdt(const void* shmaddr) 取消挂接共享内存

shmaddr:函数shmat()返回值

(5)实现

二、消息队列

1、原理

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

2、函数

(1)获取消息队列

int msgget(key_t key, int magflg)

(2)获取key

key_t ftok(const char* pathname, int proj_id)

(3)删除

int msgctl(int msgid, int cmd, struct msqid_ds* buf)

buf:输出型参数,返回消息队列具体信息

(4)发消息

int msgsnd(int msqid, const void* msgp, size_t msgsz, int msflg)

(5)查看

ipcs -q

(6)删除

ipcs -q msqid

三、信号量

1、基础知识

(1)共享资源:多执行流(进程)能看到的一份资源

(2)互斥:任何时候只有一个进程访问共享资源

(3)临界资源:被保护起来的资源,互斥可以保护

(4)程序员通过代码访问资源,代码 = 访问共享资源代码 + 不访问共享资源代码

2、信号量理解

信号量是用来保护临界资源,本质是一个计数器进行加减,当变成0时,进程就要等待。

信号量和共享内存,消息队列一样,必须让不同进程看到同一个计数器,意味着信号量也是一个共享资源,所以信号量的 -- 操作(P)和 ++ 操作(V)必须时安全的,原子的。

四、总结

操作系统如何把共享内存,消息队列,信号量管理起来?

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值