如何使用clone()系统调用代替常规的fork()+ exec()组合?

时间:2019-05-02 21:41:53

标签: c linux

是否可以使用clone()系统调用来运行新程序,就像通​​常的fork()+ exec()组合起作用一样?

我已经读过The difference between fork(), vfork(), exec() and clone()和手册页,但仍然不足以让我理解是否有这种可能

2 个答案:

答案 0 :(得分:0)

clone类似于fork,不同之处在于子ecexution上下文被限制为单个函数,您可以使用fork之类的克隆,您需要将子进程所需的任何值传递给child函数。

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

答案 1 :(得分:0)

我正在使用自己的生成功能,而在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进行调用,它将在父级与vfork相同的情况下调用clone并在子级中执行Kid挂钩(但不会出现{ {1}}(因为专用堆栈)。

这时您应该可以从孩子那里vfork,但是请记住,由于execve的语义,父级和子级的内存将共享,因此应避免异步-不安全的功能,请撤消vfork的修改。

http://git.musl-libc.org使用errno的方式与实现posix_spawn的方式类似(但不必撤消clone的更改,因为它可以使用原始的系统调用,而无需完全不要设置errno