gpt4 book ai didi

c - 为什么 glibc 的 fork 实现没有使用 sys_fork?

转载 作者:IT王子 更新时间:2023-10-29 00:31:30 28 4
gpt4 key购买 nike

在eglibc的nptl/sysdeps/unix/sysv/linux/i386/fork.c中有一个定义:

#define ARCH_FORK() \
INLINE_SYSCALL (clone, 5, \
CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0, \
NULL, NULL, &THREAD_SELF->tid)

在实际的 __libc_fork() 中用作实现的核心。但是例如在 Linux 的 arch/x86/entry/syscalls/syscall_32.tbl 中存在一个 sys_fork 条目,在 syscalls_64.tbl 中也是如此。所以显然 Linux 确实有它的特殊系统调用 fork

所以我现在想知道:如果内核已经提供了 fork 系统调用,为什么 glibc 会根据 clone 实现 fork()

最佳答案

我查看了 Ulrich Drepper 将该代码添加到 glibc 的提交,但在提交日志(或其他地方)中没有任何解释。

尽管看看 Linux 的 fork 实现:

return _do_fork(SIGCHLD, 0, 0, NULL, NULL, 0);

这里是克隆:

return _do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr, tls);

显然,它们几乎完全相同。唯一的区别是调用 clone 时,您可以设置各种标志,可以为新进程指定堆栈大小等。fork 不接受任何参数。

查看 Drepper 的代码,clone 标志是 CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD。如果使用 fork,唯一的标志将是 SIGCHLD

这是 clone 联机帮助页中关于这些额外标志的内容:

CLONE_CHILD_CLEARTID (since Linux 2.5.49)
Erase child thread ID at location ctid in child memory when the child
exits, and do a wakeup on the futex at that address. The address
involved may be changed by the set_tid_address(2) system call. This is
used by threading libraries.

CLONE_CHILD_SETTID (since Linux 2.5.49)
Store child thread ID at location ctid in child memory.

...你可以看到他确实传递了一个指针,指向内核应该首先存储子线程 ID 的位置,然后再进行 futex 唤醒。 glibc 是否正在某处对该地址进行 futex 等待?我不知道。如果是这样,那就可以解释为什么 Drepper 选择使用 clone

(如果没有,那将只是我们心爱的 glibc 的极端积累的又一个例子!如果你想找到一些漂亮、干净、维护良好的代码,请继续前进,看看在 musl libc!)

关于c - 为什么 glibc 的 fork 实现没有使用 sys_fork?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37165339/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com