【问题标题】:How can I use the clone() system call instead of the usual fork() + exec() combination? [duplicate]如何使用 clone() 系统调用而不是通常的 fork() + exec() 组合? [复制]
【发布时间】:2019-09-21 11:00:36
【问题描述】:

是否可以使用 clone() 系统调用来运行新程序,类似于通常的 fork() + exec() 组合的工作方式?

我已经阅读了The difference between fork(), vfork(), exec() and clone() 和手册页,但我仍然无法理解这样的事情是否可行

【问题讨论】:

  • 你可能真的想要posix_spawn()
  • 我知道你声称已经阅读了欺骗目标,但真的没什么好说的了。 clone() 具有记录在案的效果,该问题及其的答案很好地总结了这些效果。

标签: c linux


【解决方案1】:

我使用的是我自己的 spawn 函数,在 Linux 上我使用的是 clone,类似:

#define _GNU_SOURCE
#include <unistd.h>
#include <sched.h>
#include <signal.h>
pid_t run_kid(int Kid(void *), void *Arg, _Bool VForkEh)
{
    #if __linux__
    if(VForkEh){
        char stack[1<<13];
        return clone(Kid,stack+sizeof stack,
                CLONE_VM|CLONE_VFORK|CLONE_CHILD_SETTID|SIGCHLD,
                Arg, (void*)0/*partid,*/, (void*)0/*tls*/, (void*)0);
    }
    #endif
    pid_t r; if (0==(r=fork())) _exit(Kid(Arg));
    return r;
}

如果你在Linux上编译它并用VforkEh=1调用它,它会调用clone并在子进程中执行Kid钩子,而父进程和vfork一样被挂起(但没有vfork的问题,因为专用堆栈)。

然后你应该能够从子进程execve,但请记住,由于vfork 语义,父进程和子进程的内存将共享,因此你应该避免使用异步不安全函数并撤消errno 修改(如果有)。

http://git.musl-libc.org 以类似的方式使用clone 来实现posix_spawn(但它不必撤消errno-changes,因为它可以使用根本不设置errno 的原始系统调用) .

【讨论】:

    【解决方案2】:

    clone 类似于 fork,除了子 ecexution 上下文被限制为单个函数外,您可以像 fork 一样使用 clone,您需要将子进程所需的任何值传递给子函数。

    您可能仍需要在子函数中使用 exec。

    【讨论】:

      猜你喜欢
      • 2011-10-03
      • 2015-05-06
      • 2011-05-08
      • 2012-09-04
      • 1970-01-01
      • 2018-06-10
      • 2017-07-27
      • 2016-03-04
      • 1970-01-01
      相关资源
      最近更新 更多