Linux学习记录——이십 进程间通信(2)共享内存

这篇具有很好参考价值的文章主要介绍了Linux学习记录——이십 进程间通信(2)共享内存。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


1、system V共享内存

system是一套标准,独立于文件系统之外,是系统专门为通信而设计出来的内核模块,称之为system V的IPC通信机制。

共享内存的主要做法也是让两个毫不相关的进程看到同一份资源。

1、原理

进程的地址空间内,栈和堆区之间有个共享区,堆是向上增长,栈是向下增长,重合的那个地方就是共享区,也就是动态库存放的位置。在物理内存开辟一块空间,将这个空间通过映射到共享区里,然后把这块空间的起始地址返回给用户;同样地,另一个进程也这么做,这样两个进程就可以访问到同一个物理内存内的空间了。

如果不再继续共享了,那么进程可以取消掉映射关系,也就是修改页表,然后把地址空间的共享内存给释放掉,最后把物理内存的共享内存释放,就不再共享了。

2、模拟实现

整体代码

对照着下面的话来分析代码,从server.cc文件开始看。

Linux学习记录——이십 进程间通信(2)共享内存

shmget,申请一个System V的共享内存,是个系统调用接口,size就是申请的内存块的大大小,shmflg是大写字母,用来实际操作,代码中有写。这个函数创建成功后会返回一个共享内存的标识符,这个下标和文件下标不一样,所以实际上用得少,用文件的方法会更泛用。而key参数需要用ftok函数来设定,ftok结合传过来的项目id和路径来生成key。

上面写到了共享内存的原理,在系统中不止有一个共享内存,也不止有两个进程在共享内存,所以系统中会同时存在很多个内存,系统对他们的管理就是先描述再组织,创建一个结构体来存储共享内存的所有属性。

对于底层来说,对于共享内存的管理就变成了对结构体的管理,只要两个进程可以得到一样的数据,那就访问到了一样的共享内存。但是系统是存在很多个共享内存的,两个进程如何确保访问的是一个内存?这里就是用到了ftok函数的key,一个进程创建共享内存,指定了路径,传入了id,就会形成一个key,key会填入共享内存的结构体里,而另一个进程也调用ftok函数,它如果用同样的路径和id,也会生成一个key,然后这两个key去匹配,这是一定相等的,所以就会访问到同一个资源。

共享内存相关的进程退出了,但内存还在。要如何确定共享内存存在?

ipcs

看Shared Memory Segments那栏,也可以后面加上-m只看这栏。ipcrm 可以用来删共享内存,但应当按照key还是shmid来删?

shmid是shmget函数返回的共享内存的标识符,相当于fd。key是在系统中用的,相当于共享内存的inode。在用户层都用shmid。指令就在用户层,系统接口层之上。删除指令ipcrm -m shmid。

shmctl

这也反映了一个问题,共享内存是不随进程的,把写的模拟实现的文件生成可执行程序,调用又清除,再次调用,server会失败,因为不需要再创建了,而client可以获取和上次一样的。共享内存是随操作系统的。除了指令删除,还可以调用系统接口。

虽然创建了共享内存,但不能直接使用,要用shmat函数。

Linux学习记录——이십 进程间通信(2)共享内存

用户得到的共享内存的地址是虚拟地址。shmat参数里的shmaddr是指放在地址空间的哪里,所以一般设为None,让系统自己搞。shmflg可以设置内存块的属性,为0就是可读可写。

3.共享内存大小

上面的代码中有设置gsize = 4096,如果一边运行,一边用ipcs -m来查看进程,可以看到我们开的共享内存大小是4096。这个大小可以改,共享内存的大小是以PAGE页为单位的,它就向上对齐到PAGE,系统分配内存是以页为单位的,而这个页是4kb的大小,也就是文件和磁盘数据块进行IO时的单位。但是如果我们设定gsize为4097时,共享内存的大小应当是4096 * 2,因为4097超过了4096,按照对齐到PAGE的规则,应该是2倍的4096,但现在用命令查看却是4097。事实上,确实扩容了一下,但用户用多少系统给多少,系统确实对齐到2倍的4096了,但我只用4097,共享内存大小就是4097。

------------------------------------------------------------------------------------------------------------------------------------------------

4、共享内存特点

共享内存没有用到系统调用接口,这是因为共享内存映射到了进程地址空间,它已经被看到了,不需要用户做什么。正是因为有这种特点,可以让进程通信的时候,减少拷贝次数,所以共享内存是所有进程间通信最快的

按照上面的代码,如果client没有调用,共享内存里没有内容,只调用了server,server读取端会一直读取,会一直打印空,而管道会让读端阻塞,等到写端开始写才能继续读,所以共享内存没有保护机制(同步互斥)。

为什么共享内存有这个看似挺致命的缺点?管道是通过系统接口进行通信的,系统接口在系统内部被调用时会管理数据;共享内存直接通信。文章来源地址https://www.toymoban.com/news/detail-423305.html

到了这里,关于Linux学习记录——이십 进程间通信(2)共享内存的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Linux 共享内存mmap,进程通信

    进程间通信是操作系统中重要的概念之一,使得不同的进程可以相互交换数据和进行协作。其中,共享内存是一种高效的进程间通信机制,而内存映射(mmap)是实现共享内存的一种常见方法。 存储映射 I/O 是 一个磁盘文件 与 存储空间中的一个缓冲区相映射 。于是, 当从缓

    2024年02月13日
    浏览(42)
  • 进程间通信--共享内存详解【Linux】

    本文详细讲解了共享内存的原理和使用,并且通过实例代码角度来深度理解共享内存,下面就让我们开始吧。 数据传输:一个进程需要将它的数据发送给另一个进程 资源共享:多个进程之间共享同样的资源。 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(

    2024年02月02日
    浏览(38)
  • 【Linux】进程间通信之共享内存

    共享内存比管道快哦~ 文章目录 前言 一、共享内存的实现原理 二、实现共享内存的代码 总结 共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的

    2024年02月03日
    浏览(44)
  • 【Linux】进程间通信——管道/共享内存

    进程间通信( Inter-Process Communication,简称IPC )是指不同进程之间进行数据交换和共享信息的机制和技术。在操作系统中,每个进程都是独立运行的,有自己的地址空间和数据,因此进程之间需要一种机制来进行通信,以便彼此协调工作、共享数据或者进行同步操作。 进程间

    2024年02月16日
    浏览(39)
  • 【hello Linux】进程间通信——共享内存

    目录 前言: 1. System V共享内存 1. 共享内存的理解 2. 共享内存的使用步骤 3. 共享内存的使用         1. 共享内存的创建         查看共享内存         2. 共享内存的释放         3. 共享内存的挂接         4. 共享内存的去挂接 4. 共享内存的使用示例 1. 两进

    2024年02月01日
    浏览(90)
  • Linux--进程间的通信-共享内存

    前文: Linux–进程间的通信-匿名管道 Linux–进程间的通信–进程池 Linux–进程间的通信-命名管道 对于两个进程,通过在内存开辟一块空间(操作系统开辟的),进程的虚拟地址通过页表映射到对应的共享内存空间中,进而实现通信 ; 特点和作用: 高效性: 共享内存是一种

    2024年04月26日
    浏览(38)
  • 【Linux】进程间的通信之共享内存

    利用 内存共享 进行进程间的通信的原理其实分为以下几个步骤: 在物理内存中创建一块共享内存。 将共享内存链接到要通信的进程的页表中,并通过页表进行进程地址空间的映射。 进程地址空间映射完毕以后返回首个虚拟地址,以便于进程之间进行通信。 根据共享内存的

    2024年02月09日
    浏览(45)
  • 【Linux】进程间通信——system V共享内存

    目录  写在前面的话 System V共享内存原理 System V共享内存的建立 代码实现System V共享内存 创建共享内存shmget() ftok() 删除共享内存shmctl() 挂接共享内存shmat() 取消挂接共享内存shmdt() 整体通信流程的实现          上一章我们讲了进程间通信的第一种方式 --- 管道,这一章我

    2024年02月14日
    浏览(40)
  • 【Linux】进程间通信 -- system V共享内存

    共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据 理解: 进程间通信,是专门设计的,用来IPC 共享内存是一种通信方式,所有想通信的进程

    2024年02月16日
    浏览(42)
  • 【Linux】进程间通信之共享内存/消息队列/信号量

    共享内存是通过让不同的进程看到同一个内存块的方式。 我们知道,每一个进程都会有对应的PCB-task_struct ,独立的进程地址空间,然后通过页表将地址映射到物理内存中。此时我们就可以让OS在内存中申请一块空间,然后将创建好的内存空间映射到进程的地址空间中,两个需

    2024年02月05日
    浏览(46)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包