linux和c中两个不同独立程序之间的共享内存页面

时间:2014-01-29 12:58:32

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

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

因此当program1访问共享内存的数据时,它将从主内存加载到缓存,下次program2 / process2将从缓存中获取数据,从而降低program2 / process2相同数据的访问时间。

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

现在,我的问题如下:

  1. 两个独立程序之间可以“共享内存”自动创建吗? 意味着两个独立的程序自动可以自己或通过操作系统创建共享内存,而无需手动/编程创建共享内存,如IPC(shmget / shmat)?

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

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

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

  5. 表示在缓存中加载元素以进行求和时,其他程序将使用该缓存值。

    由于我们使用两个不同的Array,因此没有共享内存的可能性,并且元素对其他程序/进程无用。

    我在Linux下使用GCC。

3 个答案:

答案 0 :(得分:0)

您的文字令人困惑。

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

简而言之,CPU缓存对程序员的影响远远大于你可以依赖的程序,你需要与内存屏障和互斥锁进行仔细的同步,以确保你的进程(或线程)看到他们需要的数据版本看。

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

对于其他人:共享记忆(通常)既不会帮助也不会妨碍表现,如果这就是你所要求的。

答案 1 :(得分:0)

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

  2. 要回答这个问题,首先需要了解缓存未命中和页面错误之间的区别,因为页面错误就是您在这里所要求的。如果需要,共享内存可以并且实际上将由内核交换到磁盘。请记住,虚拟地址指向的物理地址可能会随着时间的推移而发生变化,甚至可能在某个时刻不在物理内存中。如果许多进程一直在使用该页面,那么它在某些条件下可能会被换掉的可能性会降低,但不要指望它。

  3. Userland程序通常不了解他们不拥有的内存。每个进程都有自己的虚拟地址空间,访问该空间外部会引发内存访问冲突。

  4. 根据经验,如果两个进程不需要访问相同的数据,则不要在它们之间共享内存。此表现的任何增加或减少都可以忽略不计。

答案 2 :(得分:0)

不,没有不相关程序的自动机制。

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