fork()内部调用clone()是否正确?
我在这里读到,clone()
系统调用用于在Linux中创建线程。现在,语法的clone()
是这样的,就需要启动程序/函数地址传递给它。
但是在此页面上,此内容是内部fork()
调用的clone()
。所以我的问题是,由子程序创建的子进程如何fork()
开始运行fork()
调用后的代码部分,即它如何不需要以函数为起点?
如果我提供的链接信息不正确,请引导我找到一些更好的链接/资源。
谢谢
回答:
对于此类问题,请始终阅读源代码。
从glibc
nptl/sysdeps/unix/sysv/linux/fork.c
(GitHub)(nptl
=
Linux的本地Posix线程)中,我们可以找到的实现fork()
,它绝对
syscall,我们可以看到魔术发生在ARCH_FORK
宏内部,该宏定义为clone()
in
nptl/sysdeps/unix/sysv/linux/x86_64/fork.c
(GitHub)的内联调用。但是,等等,没有函数或堆栈指针传递给此版本的clone()
!那么,这是怎么回事?
clone()
接下来,让我们看一下glibc
中的实现。在sysdeps/unix/sysv/linux/x86_64/clone.S
(GitHub)中。您可以看到它的作用是将函数指针保存在孩子的堆栈上,调用clone
syscall,然后新进程将读取从堆栈弹出的函数,然后对其进行调用。
所以它是这样的:
clone(void (*fn)(void *), void *stack_pointer){
push fn onto stack_pointer
syscall_clone()
if (child) {
pop fn off of stack
fn();
exit();
}
}
而且fork()
是…
fork(){
...
syscall_clone();
...
}
回答:
实际的clone()
syscall不接受函数参数,它只是从返回点继续,就像fork()
。因此clone()
和和fork()
库函数
都是clone()
syscall的包装器。
回答:
我的手册副本是关于clone()
库函数和系统调用的事实的一些预告。但是,我确实clone()
在第2节中找到了误导,而不是在第2节和第3节中都发现了这种误解。
#include <sched.h>int clone(int (*fn)(void *), void *child_stack,
int flags, void *arg, ...
/* pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );
/* Prototype for the raw system call */
long clone(unsigned long flags, void *child_stack,
void *ptid, void *ctid,
struct pt_regs *regs);
和,
该页面同时描述了glibc
clone()
包装函数和它所基于的基础系统调用。正文描述了包装函数;原始系统调用的差异将在本页尾进行描述。
最后,
原始
clone()
系统调用更紧密地对应fork(2)
于子调用中的子进程继续执行。这样,将clone()
省略包装函数的fn和arg参数。此外,参数顺序也会改变。
以上是 fork()内部调用clone()是否正确? 的全部内容, 来源链接: utcz.com/qa/401593.html