【Linux初阶】system V - 共享内存

这篇具有很好参考价值的文章主要介绍了【Linux初阶】system V - 共享内存。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

共享内存区是最快的IPC(进程间通信)形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。


一、共享内存初识

1.共享内存的原理

在物理内存中申请一块空间,将创建好的内存映射进进程的地址空间中,然后将地址空间这块区域的起始地址返回给上层用户,用户最终可以通过访问起始地址的方式实现对内存的访问。

照猫画虎,同样的一块内存空间可以映射进另一个进程的地址空间中,返回起始地址给用户,另一个进程的上层用户也可以实现的同一块内存的访问,最终实现进程间通信。

未来不想通信:a.取消进程和内存的映射关系; b.释放内存。

【Linux初阶】system V - 共享内存,Linux初阶,linux,服务器,java,c++,运维

这一块被进程共享的内存称为 共享内存。将创建好的进程映射进进程的地址空间,我们称这个步骤为进程和共享内存挂接。而取消进程与共享内存的映射我们称之为 去关联

———— 我是一条知识分割线 ————

2.理解共享内存

  1. system V - 共享内存版本的进程间通信,是专门设计的,用于IPC(进程间通信)。
  2. 共享内存是一种通信方式,所有想通信的进程,都可以使用。
  3. OS中一定会同时存在很多的共享内存。

3.共享的内存的概念

通过让不同进程,看到同一个内存块的方式,我们就称之为:共享内存


二、共享内存函数

常识补充:shm - 共享内存

1.shmget函数

功能:用来创建共享内存
原型
 int shmget(key_t key, size_t size, int shmflg);
参数
 key:这个共享内存段名字
 size:共享内存大小
 shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的
返回值:成功返回一个非负整数,即该共享内存段的标识码;失败返回-1
  • key能进行共享内存的唯一性标识,它是由 ftok() 函数得来的。
  • shmflg常见参数有两个:IPC_CREAT、IPC_EXCL。
  • IPC_CREAT- 如果不存在,创建之,如果存在,获取之。
  • IPC_EXC - 无法单独使用,使用方法: IPC_CREAT | IPC_EXC, 如果不存在,创建之,如果存在,就返回出错(说明:如果创建成功,一定是新的ssh)

共享内存 = 物理内存块 + 共享内存的相关属性,我们在申请共享内存的时候,也要对共享内存做管理,管理方法:将共享内存的属性对象用数据结构(struct shmid_ds)的方式管理起来

注意:key的信息会被 shmget函数设置进共享内存的属性对象中保存起来

2.shmat函数

功能:将共享内存段连接到进程地址空间
原型
 void *shmat(int shmid, const void *shmaddr, int shmflg);
参数
 shmid: 共享内存标识
 shmaddr:指定连接的地址
 shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回一个指针,指向共享内存第一个节;失败返回-1
  • 说明
shmaddr为NULL,核心自动选择一个地址
shmaddr不为NULL且shmflg无SHM_RND标记,则以shmaddr为连接地址。
shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会自动向下调整为SHMLBA的整数倍。公式:shmaddr - 
(shmaddr % SHMLBA)
shmflg=SHM_RDONLY,表示连接操作用来只读共享内存

3.shmdt函数

功能:将共享内存段与当前进程脱离
原型
 int shmdt(const void *shmaddr);
参数
 shmaddr: 由shmat所返回的指针
返回值:成功返回0;失败返回-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段

4.shmctl函数

功能:用于控制共享内存
原型
 int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数
 shmid:由shmget返回的共享内存标识码
 cmd:将要采取的动作(有三个可取值)
 buf:指向一个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回0;失败返回-1
  • cmd的三个可取值

【Linux初阶】system V - 共享内存,Linux初阶,linux,服务器,java,c++,运维


三、共享内存的查看方法及其特征

  • 共享内存的命令行式查看方法
ipcs -m		#查看被用户使用的共享内存
ipcrm -m shmip	  #删除特定shmip的共享内存

共享内存的特征:共享内存的生命周期是跟随OS的,不是跟随进程的。也就是说,我们需要在指令行下对自己创建的用户级共享内存进行手动删除


四、共享内存的代码实现

  • 测试代码结构
# ls
client.c comm.c comm.h Makefile server.c

# cat Makefile 
.PHONY:all
all:server client
client:client.c comm.c
	gcc -o $@ $^
server:server.c comm.c
	gcc -o $@ $^
.PHONY:clean
clean:
	rm -f client server
  • comm.h
#ifndef COMM_H //把头文件的内容都放在#ifndef和#endif中,可避免头文件被多个文件引用产生的冲突
#define COMM_H

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define PATHNAME "."
#define PROJ_ID 0x6666

int createShm(int size);
int destroyShm(int shmid);
int getShm(int size);

#endif
  • comm.c
#include "comm.h"

static int commShm(int size, int flags)
{
	key_t _key = ftok(PATHNAME, PROJ_ID);
	if (_key < 0) {
		perror("ftok");
		return -1;
	}
	int shmid = 0;
	if ((shmid = shmget(_key, size, flags)) < 0) {
		perror("shmget");
		return -2;
	}
	return shmid;
}

int destroyShm(int shmid)
{
	if (shmctl(shmid, IPC_RMID, NULL) < 0) {
		perror("shmctl");
		return -1;
	}
	return 0;
}

int createShm(int size)
{
	return commShm(size, IPC_CREAT | IPC_EXCL | 0666);
}

int getShm(int size)
{
	return commShm(size, IPC_CREAT);
}
  • server.c
#include "comm.h"

int main()
{
	int shmid = createShm(4096);

	char* addr = shmat(shmid, NULL, 0);
	sleep(2);
	int i = 0;
	while (i++ < 26) {
		printf("client# %s\n", addr);
		sleep(1);
	}

	shmdt(addr);
	sleep(2);
	destroyShm(shmid);
	return 0;
}
  • client.c
#include "comm.h"

int main()
{
	int shmid = getShm(4096);
	sleep(1);
	char* addr = shmat(shmid, NULL, 0);
	sleep(2);
	int i = 0;
	while (i < 26) {
		addr[i] = 'A' + i;
		i++;
		addr[i] = 0;
		sleep(1);
	}

	shmdt(addr);
	sleep(2);
	return 0;
}
  • 运行结果

【Linux初阶】system V - 共享内存,Linux初阶,linux,服务器,java,c++,运维

  • ctrl+c终止进程,再次重启
# ./server 
shmget: File exists

# ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status 
0x66026a25 688145 root 666 4096 0 
 
# ipcrm -m 688145 #删除shm ipc资源,注意,不是必须通过手动来删除,这里只为演示相关指令,删除IPC资源是进
程该做的事情

五、共享内存优缺点分析

1.共享内存的优点

优点:在所有进程间通信的方法中,共享内存的速度是最快的

如果使用管道,用户拷贝 6次,键盘的输入数据 -> 语言级缓冲区 -> 进程对应的文件缓冲区 -> 管道 -> 另一个进程对应的文件缓冲区 -> 语言级缓冲区 -> 屏幕。

如果使用共享内存,用户拷贝 4次,键盘的输入数据 -> 语言级缓冲区 -> 共享内存 -> 语言级缓冲区 -> 屏幕。

我们知道,在企业的数据通信中,数据往往非常庞大,此时使用共享内存可以大大降低拷贝次数

2.共享内存的缺点

缺点:共享内存不会给我们进行同步和互斥操作,没有对我们的数据做任何保护

也就是说,共享内存没有对写端在写、读端不读,写端不写、读端一直读,共享内存数据已满等情况,做相应的阻塞或其他保护。

通常情况下,工程师们会对共享内存进行一定的封装,实现对共享内存的保护。


六、共享内存内核数据结构理解

下面是共享内存暴露给用户的用户级数据结构:

struct shmid_ds {
 struct ipc_perm shm_perm; /* operation perms */
 int shm_segsz; /* size of segment (bytes) */
 __kernel_time_t shm_atime; /* last attach time */
 __kernel_time_t shm_dtime; /* last detach time */
 __kernel_time_t shm_ctime; /* last change time */
 __kernel_ipc_pid_t shm_cpid; /* pid of creator */
 __kernel_ipc_pid_t shm_lpid; /* pid of last operator */
 unsigned short shm_nattch; /* no. of current attaches */
 unsigned short shm_unused; /* compatibility */
 void *shm_unused2; /* ditto - used by DIPC */
 void *shm_unused3; /* unused */
};

在上文中我们就曾学习过,在内核层面上,为了帮助不同的进程能找到同一块共享内存,我们有 key存在于共享内存的数据结构对象中,它可以让不同进程确定是否看到的是同一块共享内存

此时问题来了,为什么我没有在你的数据结构中找到 key的信息呢?事实上,我们看不到 key,是因为设计者对其做了相应的封装,它就被保存在了下面这个结构体中:

 struct ipc_perm shm_perm; /* operation perms */

【Linux初阶】system V - 共享内存,Linux初阶,linux,服务器,java,c++,运维

程序获取共享内存部分数据结构展示:

	printf("获取属性: size: %d, pid: %d, myself: %d, key: 0x%x", \
            ds.shm_segsz, ds.shm_cpid, getpid(), ds.shm_perm.__key);

输出结果如下:

【Linux初阶】system V - 共享内存,Linux初阶,linux,服务器,java,c++,运维


结语

🌹🌹 system V - 共享内存 的知识大概就讲到这里啦,博主后续会继续更新更多C++ 和 Linux的相关知识,干货满满,如果觉得博主写的还不错的话,希望各位小伙伴不要吝啬手中的三连哦!你们的支持是博主坚持创作的动力!💪💪文章来源地址https://www.toymoban.com/news/detail-645500.html

到了这里,关于【Linux初阶】system V - 共享内存的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 简单对已有云服务器进行linux环境搭建以及共享服务器

    外壳程序:Xshell7 云服务器:华为云 服务器操作系统:centos7 区域尽量选择距离所处地距离自己最近的区域。 镜像这里选择的为centos7.6-7.9,最好不要超过8 ,8的生态环境较差且已经停止更新和维护了,7完全够用。 进入所买服务器网站,找到所买的服务器实例, 重新设置密码。

    2024年03月22日
    浏览(78)
  • [Linux打怪升级之路]-system V共享内存

    前言 作者 : 小蜗牛向前冲 名言 : 我可以接受失败,但我不能接受放弃   如果觉的博主的文章还不错的话,还请 点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 本期学习目标:认识什么是 system V共享内存,认识共享内存的接口函数,学会

    2024年02月08日
    浏览(46)
  • 【Linux从入门到精通】通信 | 共享内存(System V)

        本篇文章接着上篇文章通信 | 管道通信(匿名管道 命名管道)进行讲解。本篇文章的中点内容是 共享内存 。 文章目录  一、初识与创建共享内存 1、1 什么是共享内存 1、2 共享内存函数 1、2、1 创建共享内存 shmget 1、2、2 ftok 生成 key 1、2、3 获取共享内存 shmget 1、3 dem

    2024年02月09日
    浏览(43)
  • 【Linux】System V 共享内存、消息队列、信号量

    🍎 作者: 阿润菜菜 📖 专栏: Linux系统编程 System V 共享内存是一种进程间通信的机制,它允许多个进程 共享一块物理内存区域 (称为“段”)。System V 共享内存的优点是效率高,因为进程之间不需要复制数据;缺点是 需要进程之间进行同步,以避免数据的不一致性 。 共

    2024年02月04日
    浏览(50)
  • Linux服务器配置指南:网络、用户管理、共享服务及DNS配置详解

    💂 个人网站:【 海拥】【神级代码资源网站】【办公神器】 🤟 基于Web端打造的:👉轻量化工具创作平台 💅 想寻找共同学习交流的小伙伴,请点击【全栈技术交流群】 设置虚拟机的网卡为仅主机模式,并要求服务器采用双网卡, ens33 IP地址设置为192.168. 5.x/24(其中x学号),

    2024年02月05日
    浏览(58)
  • 【Linux网络服务】Centos7搭建nfs文件共享服务器

    1.NFS介绍 2.环境准备 3.在A服务端机器安装nfs-utils和rpcbind包 4.启动rpcbind检查是否启动了rpcbind服务并监听111端口 5.配置NFS服务的配置文件,参数配置:vi /etc/exports 数据同步与数据异步的区别 数据同步:当系统从内存中向磁盘中持久化数据时,同步发送表示只有当内存中的数据

    2024年02月06日
    浏览(63)
  • Linux服务器增加虚拟交换内存

    使用dd命令创建名为swapfile 的swap交换文件(文件名和目录任意): dev/zero是Linux的一种特殊字符设备(输入设备),可以用来创建一个指定长度用于初始化的空文件,如临时交换文件,该设备无穷尽地提供0,可以提供任何你需要的数目。 bs=1024 :单位数据块(block)同时读入/输出

    2024年02月15日
    浏览(54)
  • 【Linux】进程间通信——system V共享内存 | 消息队列 | 信号量

    共享内存是一种在多个进程之间进行进程间通信的机制。它允许多个进程访问相同的物理内存区域,从而实现高效的数据交换和通信。 因为 进程具有独立性(隔离性) ,内核数据结构包括对应的代码、数据与页表都是独立的。OS系统为了让进程间进行通信,必须让不同的进

    2024年02月15日
    浏览(52)
  • linux服务器查看cpu和内存

    cat /proc/cpuinfo | grep \\\"physical id\\\" | sort | uniq | wc -l cat /proc/cpuinfo | grep \\\"cpu cores\\\" | uniq grep processor /proc/cpuinfo|wc -l cat /proc/cpuinfo |grep MHz|uniq less /proc/cpuinfo |grep model free -m free -h

    2024年02月05日
    浏览(72)
  • Linux 查看服务器内存、CPU 命令

    1 查看物理CPU个数:         Procs(进程) 2 查看服务器CPU内核个数 1 linux查看系统内存(硬盘) 2 查看服务器硬盘(当前文件夹下)使用率: 3 查看服务器硬盘(所有文件占用率)使用率: 1 查看内存,不带单位 2 查看内存使用情况,带单位,显示查看结果 显示的参数:       

    2024年02月15日
    浏览(67)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包