为何在C语言中调用fork()函数实际触发的是sys_clone()系统调用而非sys_fork()?
Problem Description
I wrote this C test code (test.c):
#include <stdio.h> #include <unistd.h> #include <stdlib.h> int main(){ pid_t pid; pid=fork(); if(pid==0){ printf("new process\n"); }else{ printf("old process\n"); } return 0; }
I compiled it with:
gcc test.c -o fork
Then I used strace to trace the program execution, and found that the program actually calls the clone() system call instead of fork():
$ strace -o my ./fork new process old process $ cat my | grep clone clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f459f17d810) = 4415 $ cat my | grep fork execve("./fork", ["./fork"], 0x7ffc76ccbf00 /* 52 vars */) = 0
Why is this happening? Why isn't the program directly calling the sys_fork() system call?
Answer
Great question! Let's break this down clearly:
fork()is a library wrapper, not a raw system call
Thefork()you call in your code is a higher-level function provided by the GNU C Library (glibc), not the direct kernel system call. Glibc provides this wrapper to abstract away low-level system call details, making it easier for developers to use standard process-creation behavior without manual parameter setup.clone()is Linux's flexible underlying process-creation system call
On Linux,clone()is the generalized system call for creating new processes (or threads). It lets you precisely control which resources the new process shares with the parent—like memory, file descriptors, or signal handlers—via its flags parameter. This flexibility makes it the go-to primitive for all process/thread creation on modern Linux.Glibc's
fork()usesclone()to mimic classic behavior
The glibc implementation offork()invokesclone()with specific flags that replicate the traditionalfork()behavior:CLONE_CHILD_CLEARTIDandCLONE_CHILD_SETTIDhandle internal thread ID bookkeeping (even for single-threaded processes, glibc relies on these for consistency)SIGCHLDensures the parent receives aSIGCHLDsignal when the child exits, which is the standardfork()behavior
What about
sys_fork()?
While older Linux kernels had a dedicatedsys_fork()system call, modern Linux doesn't expose it directly to user-space via glibc. Instead, glibc uses the more versatileclone()to implement all process-creation functions—includingfork(),vfork(), and evenpthread_create()for threads. This approach lets glibc maintain consistent behavior across kernel versions while leveraging the most efficient underlying mechanism.
In short: your code calls the glibc fork() wrapper, which in turn uses clone() with the right flags to deliver the classic fork() functionality you expect.
内容的提问来源于stack exchange,提问作者Duowen

