2

不知何故,它更容易调用fork,然后unshare因为许多参数是通过复制fork的,否则会被手动包装到clone. clone我的问题是,(1)调用在单独的命名空间中分叉一个新进程和(2)fork+unshare分叉一个新进程然后离开父命名空间有什么区别。假设传递给clone和的所有命名空间标志unshare都是相同的。

auto flag = CLONE_NEWUSER | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWNET | SIGCHLD;

因此,使用 fork,孩子很容易重用从父母那里继承的数据。

int mydata;  // this could be even more complicated, class, struct, etc.
auto pid = fork();
if(pid == 0) {
  // reuse inherited data in a copy-on-write manner
  unshare(flag);
}

对于克隆,我们有时必须将数据包装到另一个结构中并将其传递void*clone系统调用。

int mydata;
clone(func, stack+stack_size, flag, &wrapper_of_data);

在我看来,在上面的例子中,唯一的区别是性能下降,而 fork 可能会更贵一些。但是,fork两者都可以在新的命名空间中创建进程的方式为我节省了很多精力。

4

1 回答 1

0

不知何故,调用 fork 然后取消共享更容易,因为许多参数是通过 fork 复制的,否则这些参数将被手动包装到克隆。

这仅适用于 libc 包装函数。
底层系统调用更像 fork(),在这种情况下可能会更好地工作:

long flags = CLONE_NEWUSER | ... | SIGCHLD;
long pid = syscall(__NR_clone, flags, 0, 0, 0, 0);

if(pid == 0) {
    /* child with unshared namespaces */
}

由于大约在引入克隆系统调用的时候,fork() 只是克隆的一个特定情况,标志=SIGCHLD,所有其他参数都为 0。

可能没有理由更喜欢 fork/unshare 对而不是仅将相同的标志传递给克隆。

于 2016-11-29T01:58:03.893 回答