【问题标题】:Shared memory pages between two different independent program in linux and clinux和c中两个不同独立程序之间的共享内存页面
【发布时间】:2014-02-21 07:13:32
【问题描述】:

我从here 了解到共享内存。根据文档,两个不同的程序生成两个不同的虚拟地址,这些虚拟地址映射到 RAM 中的同一物理页面。

所以当program1访问共享内存的数据时,它会从主内存加载到缓存中,下次program2/process2会从缓存中获取数据,因此program2/process2对相同数据的访问时间会更短。

我已经成功地用 C 语言为 IPC 编写了一个程序,它使用共享内存在两个程序之间进行通信,并修改一个程序中的变量并从另一个程序中读取。

现在,我的问题如下:

  1. 可以在两个独立程序之间自动创建“共享内存”吗? 意味着两个独立的程序是否有可能自动自行或由操作系统创建共享内存,而无需像 IPC (shmget/shmat) 那样手动/以编程方式创建共享内存?

  2. 当两个不同的虚拟地址使用共享内存映射到同一个物理内存时,这两个程序的公共数据是否存在总是正确的,或者在该共享内存位置可能存在不同的数据(这会导致更多的缓存未命中)?

  3. 我们能否在不了解其他程序的情况下决定或创建两个独立程序之间的共享内存?

  4. 假设,在程序 1 中我声明了大小为 1 MB 的 Array-A,在程序 2 中我声明了 Array-B 大小为 16KB。现在在两个程序中执行求和操作时,它是否仍会因共享内存而受益?

意味着当一个元素被加载到缓存中进行求和时,其他程序将使用该缓存值。

没有共享内存的可能性,因为我们使用了两个不同的数组,并且其中的元素对其他程序/进程没有用。

我在 Linux 下使用 GCC。

【问题讨论】:

  • 旁注:shm_open 优于 shmget
  • 我想你不认为分叉程序独立于其父程序?
  • @SirDarius,我正在考虑两个不同的程序,我没有使用任何 fork 来创建子进程。

标签: c linux memory-management cpu-architecture cpu-cache


【解决方案1】:
  1. 当您fork 一个进程时,操作系统实际上会执行此操作。在这种情况下,实际代码所在的内存区域在两个进程之间共享(直到子进程想要在其内存上写入,它也共享数据所在的区域。这种机制称为写时复制)。使用线程api创建进程时(因为Linux中的线程是作为进程实现的),两个线程共享相同的内存区域(但每个线程都运行在自己的调用堆栈上)

  2. 要回答这个问题,首先您需要了解缓存未命中和页面错误之间的区别,因为页面错误就是您在此处询问的内容。如果需要,共享内存可以并且确实会被内核换出到磁盘。请记住,虚拟地址指向的物理地址可能会随着时间而改变,甚至可能在某一时刻都不在物理内存中。如果许多进程一直在使用该页面,那么在某些情况下它被换出的可能性可能会降低,但不要指望这一点。

  3. Userland 程序通常对它们不拥有的内存一无所知。每个进程都有自己的虚拟地址空间,在该空间之外的访问会引发内存访问冲突。

  4. 根据经验,如果两个进程不需要访问相同的数据,则不会在它们之间共享内存。对此性能的任何提高或降低都可以忽略不计。

【讨论】:

    【解决方案2】:

    您的文字令人困惑。

    首先,共享内存与 CPU 缓存(L1、L2...)几乎没有关系。无论内存是通过 shm* 还是其他方式共享,CPU 缓存对从多个进程或多个线程访问内存区域的影响总是相同的。这是一个非常高级的主题,但这里有一些文档可以帮助您入门:

    简而言之,CPU 缓存对程序员来说更像是一个障碍,而不是你可以依赖的东西,你需要小心地与内存屏障和互斥锁同步,以确保你的进程(或线程)看到他们需要的数据版本去看看。

    对于问题 #1:您可以创建线程,这些线程有时也称为轻量级进程,它们将共享其进程的整个内存空间。如果您 fork 一个进程并且该进程具有共享内存(由您显式创建),则新进程将继承共享内存。除此之外,不,通常不会在进程之间任意共享内存。

    对于其他人:共享内存(通常)既不会帮助也不会妨碍性能,如果这就是您所要求的。

    【讨论】:

    • @Ivan,感谢您的回答。您说“共享内存与 CPU 缓存(L1,L2 ...)几乎没有关系。”这是错误的。正如我所说,这两个程序都在使用共享内存。因此,如果一个程序正在访问共享内存页面,它将被加载到缓存中,然后第二个进程将从缓存中访问这些共享内存数据。
    • 我说的和你说的是两个不同的东西。当且仅当您考虑使用单 CPU 机器并且进程之间的上下文切换使得 CPU 缓存不被刷新时,您的陈述可能是正确的。否则,确实,在进程之间共享一些内存不会影响内存的缓存方式。
    【解决方案3】:

    不,不存在无关程序的自动机制。

    您要做的是定义两个程序都知道用于共享内存的文件路径。然后您将使用mmap 将文件的页面映射到内存。我建议映射 4096 字节块的倍数。

    【讨论】:

    • @Neal,感谢您的回答。在我知道其他程序像任何特定库一样使用什么之后,我可以设计我的程序来定义共享内存吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-27
    • 2014-07-18
    • 2013-05-09
    • 2010-11-15
    • 1970-01-01
    • 2018-06-04
    • 2011-12-15
    相关资源
    最近更新 更多