Is it true that fork() calls clone() internally?

前端 未结 2 1440
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-07 11:21

I read here that clone() system call is used to create a thread in Linux. Now the syntax of clone() is such that a starting routine/function addres

2条回答
  •  渐次进展
    2020-12-07 11:46

    @Dietrich did a great job explaining by looking at the implementation. That's amazing! Anyway, there's another way of discovering that: by looking at the calls strace "sniffs".

    We can prepare a very simple program that uses fork(2) and then check our hypothesis (i.e, that there's no fork syscall really happening).

    #define WRITE(__fd, __msg) write(__fd, __msg, strlen(__msg))
    
    int main(int argc, char *argv[])
    {
      pid_t pid;
    
      switch (pid = fork()) {
        case -1:
          perror("fork:");
          exit(EXIT_FAILURE);
          break;
        case 0:
          WRITE(STDOUT_FILENO, "Hi, i'm the child");
          exit(EXIT_SUCCESS);
        default:
          WRITE(STDERR_FILENO, "Heey, parent here!");
          exit(EXIT_SUCCESS);
      }
    
      return EXIT_SUCCESS;
    }
    

    Now, compile that code ( clang -Wall -g fork.c -o fork.out ) and then execute it with strace:

    strace -Cfo ./fork.strace.log ./fork.out
    

    This will intercept system calls called by our process (with -f we also intercept the child's calls) and then put those calls into ./fork.trace.log; -c option gives us a summary at the end). The result in my machine (Ubuntu 14.04, x86_64 Linux 3.16) is (summarized):

    6915  arch_prctl(ARCH_SET_FS, 0x7fa001a93740) = 0
    6915  mprotect(0x7fa00188c000, 16384, PROT_READ) = 0
    6915  mprotect(0x600000, 4096, PROT_READ) = 0
    6915  mprotect(0x7fa001ab9000, 4096, PROT_READ) = 0
    6915  munmap(0x7fa001a96000, 133089)    = 0
    6915  clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fa001a93a10) = 6916
    6915  write(2, "Heey, parent here!", 18) = 18
    6916  write(1, "Hi, i'm the child", 17 
    6915  exit_group(0)                     = ?
    6916  <... write resumed> )             = 17
    6916  exit_group(0)                     = ?
    6915  +++ exited with 0 +++
    6916  +++ exited with 0 +++
    % time     seconds  usecs/call     calls    errors syscall
    ------ ----------- ----------- --------- --------- ----------------
     24.58    0.000029           4         7           mmap
     17.80    0.000021           5         4           mprotect
     14.41    0.000017           9         2           write
     11.02    0.000013          13         1           munmap
     11.02    0.000013           4         3         3 access
     10.17    0.000012           6         2           open
      2.54    0.000003           2         2           fstat
      2.54    0.000003           3         1           brk
      1.69    0.000002           2         1           read
      1.69    0.000002           1         2           close
      0.85    0.000001           1         1           clone
      0.85    0.000001           1         1           execve
      0.85    0.000001           1         1           arch_prctl
    ------ ----------- ----------- --------- --------- ----------------
    100.00    0.000118                    28         3 total
    

    As expected, no fork calls. Just the raw clone syscall with its flags, child stack and etc properly set.

提交回复
热议问题