【问题标题】:Shmat with non-null shmaddr具有非空 shmaddr 的 shmat
【发布时间】:2011-01-14 19:19:17
【问题描述】:

有人可以提供一个(合理地)使用带有非空第二个参数的函数 shmat() 的示例吗?

手册说:

#include <sys/shm.h>

void *shmat(int shmid, const void *shmaddr, int shmflg);

shmat() 函数将与共享内存标识符 shmid 关联的共享内存段附加到调用进程的数据段。该段附加到由以下条件之一指定的地址:

  • 如果 shmaddr 是 NULL 指针,则将段附加到系统选择的第一个可用地址。
  • 如果 shmaddr 不是 NULL 指针并且 (shmflg & SHM_RND) 不为零,则该段附加在 (shmaddr - (shmaddr % SHMLBA)) 给出的地址处。
  • 如果 shmaddr 不是 NULL 指针且 (shmflg & SHM_RND) 为 0,则该段附加到 shmaddr 给出的地址。

但我从未见过任何将 shmat 与任何东西一起使用的示例,但 shmaddr 设置为 NULL。在我的项目中,一个进程必须将它附加到malloc()'ed 的内存块上,并且可以很好地使用它,然后另一个进程获取指向该共享内存的指针(通过 shmid),然后在尝试访问内存。

【问题讨论】:

    标签: c linux posix shared-memory


    【解决方案1】:

    这里的想法是将共享段放置在不同进程中的相同虚拟地址,以便它们可以使用普通指针(而不是偏移量)来寻址共享内存中的项目。常见的情况是单个“主”进程将内存映射到内核提供的地址(第二个参数为零),然后通过一些带外通道将该地址传递给“工作”进程(如带有 fork/exec、UNIX 套接字、FIFO 等的命令参数),然后“工作人员”尝试将段映射到该地址。同样,这个想法是,如果内核能够为“主”映射给定 VA 的共享内存,那么对于“工作”进程来说,相同的地址应该没问题。

    我没有一个“合理”的例子可以指出。你可以看看Postgres 是如何与共享内存一起工作的。不过有点牵强。

    【讨论】:

    • ...但是如果“工人”对 shmget 使用相同的密钥,他们就不需要地址 - shmat 将返回一个指针,指向与 shmaddr 相同的(已经创建的)共享内存块=NULL 一样。区别在哪里?
    • 不同之处在于共享内存在所有通信进程中被映射到完全相同的虚拟地址,因此一个进程可以在那里存储指针(当然仅限于共享段),其他进程可以直接使用它们.
    【解决方案2】:

    我想这是为了让您可以共享一个包含绝对指针的结构。

    但我没有任何代码示例。

    【讨论】:

      猜你喜欢
      • 2012-01-16
      • 2017-10-06
      • 2013-05-07
      • 2018-09-20
      • 2020-03-08
      • 2020-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多