【问题标题】:Is it possible using Linux's clone() system call to run multiple applications in the same address space?是否可以使用 Linux 的 clone() 系统调用在同一地址空间中运行多个应用程序?
【发布时间】:2009-10-29 23:46:47
【问题描述】:

如果您没有将 CLONE_VM 标志传递给 clone(),那么新进程将与原始进程共享内存。这可以用来让两个不同的应用程序(两个 main()'s)在同一个进程中运行吗?理想情况下,这就像使用 CLONE_VM 调用 clone() 然后调用 exec() 一样简单,但我意识到它可能涉及更多。至少,我假设生成的应用程序需要编译为可重定位(-fPIC)。我意识到我总是可以将应用程序重新编码为库,并创建一个主应用程序,将其他“应用程序”作为线程产生,但我很好奇这种方法是否可行。

【问题讨论】:

    标签: linux linker exec fork system-calls


    【解决方案1】:

    嗯,是的,这就是线程,减去“两个不同的 main()/应用程序”部分。

    其实clone(2)的原因是为了实现线程。

    Clone(2) 或多或少要求您声明一个单独的堆栈(如果您不创建一个堆栈),因为没有它,子进程将无法从当前调用级别返回而不会破坏父级堆栈。

    一旦您开始为每个进程设置堆栈,那么您不妨只使用 posix 线程库。

    至于加载两个不同应用程序的部分,调用execve(2) 很可能不是这样做的方法。如今,内核无论如何都不能精确地运行程序。更典型的做法是将映像设置为运行 Elf 动态加载程序,这就是内核真正运行的全部内容。然后加载程序将mmaps(2)s 进程及其库放入地址空间。当然可以这样做以获得“两个不同的应用程序”,并且线程调度程序很乐意通过 clone(2) 将它们作为两个进程运行。

    【讨论】:

      【解决方案2】:

      为什么不将应用程序编译成同一个可执行文件,然后在 main 中将它们作为线程启动?

      将它们作为单独的任务运行有什么问题?如果你真的愿意,你仍然可以共享内存。

      【讨论】:

      • 想象一下你有两个旧的笨拙的软件,它们充满了重叠的全局变量名称或函数。尝试将它们编译到同一个应用程序中会导致错误。
      • 实际上,更好的例子:您意识到当您同时运行两个应用程序时,上下文切换会成为瓶颈。因此,您希望在同一地址空间中运行两个应用程序,这样 TLB 就不必被换出。
      • 这种上下文切换真的会成为瓶颈吗?您是否在具有更多内核的机器上尝试过?大多数现在至少有两个。
      【解决方案3】:

      简短的回答:这是不可能的。

      好吧,如果您愿意编写自己的自定义 ELF 加载器并模拟内核通常为进程所做的许多事情,这是可能的。

      最好将每个应用程序编译成一个库,该库只公开一个函数 main(重命名为其他函数)。然后主存根程序应该与两个库链接并调用每个库的导出函数。

      【讨论】:

        猜你喜欢
        • 2011-10-31
        • 1970-01-01
        • 2015-07-21
        • 1970-01-01
        • 1970-01-01
        • 2019-12-14
        • 1970-01-01
        • 2022-08-17
        • 1970-01-01
        相关资源
        最近更新 更多