【问题标题】:Clone, fork, vfork behaviour when followed by an exec紧跟 exec 时的克隆、fork、vfork 行为
【发布时间】:2012-08-01 07:35:05
【问题描述】:

我很好奇从设置了大多数标志的进程调用 clone 的行为(这样两个进程共享一个执行上下文,即共享地址空间、文件描述符 talbe 等)。我无法使用在线材料完全回答我的问题。

现在假设我从克隆的进程中调用 execve。这会将进程的映像替换为全新的映像,破坏附加的内存段,丢弃分配的内存等,但是父进程会发生什么?给定这些共享(例如,所有分配的内存区域),它们是否也会被释放?

新执行的进程是否仍与父进程共享地址空间?

【问题讨论】:

  • clone 在 Linux 中用于实现线程创建 (pthread_create) 和进程创建 (fork)。 execve 替换整个进程。

标签: c multithreading process fork system-calls


【解决方案1】:

父进程不受 execve 影响。毕竟这是一个不同的过程。进程总是必须使用一些显式的方法进行通信(文件、管道、IPC,如共享内存、信号……)。由于所有这些都在执行 exec 的子进程中被破坏,因此在再次明确设置之前无法进行通信。

【讨论】:

  • 是的,但是如果您只使用克隆,您可以简单地通过共享指针进行通信(假设您使用带有 CLONE_VM 标志集的克隆)
  • 但是在 execve 没有共享指针之后你怎么能做到呢?我们中的一个人误解了 execve 的作用……是我吗?
【解决方案2】:

共享对象未映射或未链接,但从共享的角度来看。

假设您有 3 个进程/线程,它们都从 0x1000 开始共享内存。

其中一个执行 execve。然后它将在 0x1000 上执行shm_unlink(2)shm_unlink(2) 会尝试unlink(2) 它。

现在对于使用该内存范围的每个进程/线程都有一个计数器。在我们的例子中,计数器在execve(2) 之前设置为 3,之后将设置为 2。没有失忆。

正如您所说,当没有进程不再使用它时,内存将被“销毁”。当计数器为 0 时。

所有共享对象也是如此。有关调用哪些系统调用以及它们如何“破坏”共享对象的列表,请查看execve(2)manpage 中的链接。搜索这个短语:

All process attributes are preserved during an execve(), except the following

【讨论】:

  • 我明白了。我不清楚内存是否被释放或只是取消链接。现在换一种方式:如果 execved 进程执行 malloc 并以某种方式将其传达给父​​进程,父进程是否能够通过指向该地址的指针来访问它(阅读:即使我调用了 execve ,他们是否继续共享相同的内存地址空间,就像他们在克隆后但在执行之前一样?)?
  • 如果我正确理解您的问题,答案是否定的。如果 execve(2) 成功执行,您将获得一个新进程。不是新线程。所以不会有共享地址空间。
  • 这是否意味着无法在同一个地址空间内运行两个二进制文件? (假设他们都是可信的)
  • 不。您必须使用某种形式的 IPC 或找到实现第二个二进制文件功能的库。
猜你喜欢
  • 2011-06-18
  • 1970-01-01
  • 2021-06-07
  • 1970-01-01
  • 2011-03-29
  • 2011-05-14
  • 2013-12-17
  • 1970-01-01
  • 2011-02-08
相关资源
最近更新 更多