【问题标题】:How to pass mmap to execve function in C?如何将 mmap 传递给 C 中的 execve 函数?
【发布时间】:2017-11-05 17:36:47
【问题描述】:

我正在 Linux 中编码并尝试通过执行另一个程序来完成某些任务。

主服务器必须执行从服务器以对某些输入文件进行一些单词搜索(每个从服务器 1 个文件)。 完成所有搜索后,主进程会将从进程找到的匹配行写入输出文件。我正在尝试使用命名共享内存在主从之间进行通信。

我需要将我的 mmap 调用的指针在 master 的 main 中传递给另一个程序并在那里获取它,但我不能,因为它的类型不匹配。

如果我使用信号量进行同步,我还需要传递共享信号量的 mmap。下面有一个来自调用者main 的代码sn-p 来执行slave。我可以通过在 slave 的 main 中使用 argv 来达到 newArgv:

int f = open(argv[1], O_RDWR);

unsigned int *addr = mmap(0, 10000, PROT_READ | PROT_WRITE, MAP_SHARED, f, 0);

char * newArgv[10];
for (int a = 0; a < numberOfFiles; a++) {
    newArgv[0] = wordToSearch;
    newArgv[1] = argv[3 + a];
    char * path = "./psearch2aslave";
    execve(path, newArgv, NULL);
}

【问题讨论】:

  • 不要传递指针……反正它不会是同一个指针。如果你得到一本合适的操作系统书籍并阅读了它的 IPC 章节,它应该说匿名 mmap 将不支持任何进程之间的 IPC。你可能想映射到一个实际的文件,传递文件名。
  • 如果我通过名字,使用mmap没有意义。这不是匿名 mmap,它是命名共享内存
  • 我没有看到你在传递名字。您传递的是 null,因此是匿名的。
  • 如果我传递 0 而不是 NULL,有没有办法使用我们传递的 0 在另一个程序中到达 mmap 的地址?谢谢你的警告,我不应该不检查就直接复制旧程序的代码。
  • 我不确定你的问题是什么。 null 实际上定义为(void *)0。您需要传递一个真实的文件名,以便可以在任何两个进程之间建立 IPC。再次,匿名 mmap 不会任意工作。除了clone 通话的直接后果之外,我的无知使我无法提出功能性案例。

标签: c pointers shared-memory mmap


【解决方案1】:

您不能将mmap 传递给execve-ed 可执行文件。

execve 成功时,整个virtual address space 被抓取并为执行的ELF 二进制文件重新初始化。这是execve(2) 的主要作用之一。在启动时,程序应该期待一个明确定义的内存状态。

也许您可能会采用一个约定,例如使用某个命名文件,并将该文件的名称作为某个程序参数传递。或者传递文件描述符等。

(IIRC,多年前有人提出了一个内核补丁,为mmap(2) 添加一个标志,用于在execve 上持久的内存映射;该补丁被拒绝了,有充分的理由;我完全忘记了细节,可以大错特错)

也许你想要shm_overview(7)。或者只是采用一些文件名的约定并将mmapMAP_SHARED一起使用。

请注意,即使您共享(虚拟)内存,也需要一些同步方式。阅读sem_overview(7), futex(7), ....

另请阅读ALPOperating Systems: Three Easy Pieces(均可免费下载)。另见syscalls(2)(有几种方法可以做到inter-process communication)。

【讨论】:

  • 也可以将文件描述符传递给 exec。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-21
  • 1970-01-01
  • 2013-10-06
  • 1970-01-01
  • 2015-05-02
  • 1970-01-01
相关资源
最近更新 更多