创建进程准备

linux创建进程/线程通过用户空间的fork()、vfork()、__clone()函数实现,这些函数会通过传递不同的参数给调用系统调用clone(),然后clone()再调用do_fork()去实现创建进程/线程的主要部分。

fork与vfork都以写时拷贝技术(cow)创建进程/线程,并且内核会优先让子进程投入运行。vfork不会复制页表项,并且vfork会让子进程信号通知才唤醒父进程,然后从do_fork函数返回。

创建进程与线程不同在于是否共享一些资源,包括进程地址空间、文件系统资源、文件描述符资源、信号处理函数、命名空间等。

clone参数标志定义在/include/linux/sched.h中,如下:

  1. // 向下滚动
  2. /*
  3. * cloning flags:
  4. */
  5. #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
  6. #define CLONE_VM 0x00000100 /* set if VM shared between processes */
  7. #define CLONE_FS 0x00000200 /* set if fs info shared between processes */
  8. #define CLONE_FILES 0x00000400 /* set if open files shared between processes */
  9. #define CLONE_SIGHAND 0x00000800 /* set if signal handlers and blocked signals shared */
  10. #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
  11. #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
  12. #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
  13. #define CLONE_THREAD 0x00010000 /* Same thread group? */
  14. #define CLONE_NEWNS 0x00020000 /* New namespace group? */
  15. #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
  16. #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
  17. #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
  18. #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
  19. #define CLONE_DETACHED 0x00400000 /* Unused, ignored */
  20. #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
  21. #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
  22. #define CLONE_STOPPED 0x02000000 /* Start in stopped state */
  23. #define CLONE_NEWUTS 0x04000000 /* New utsname group? */
  24. #define CLONE_NEWIPC 0x08000000 /* New ipcs */
  25. #define CLONE_NEWUSER 0x10000000 /* New user namespace */
  26. #define CLONE_NEWPID 0x20000000 /* New pid namespace */
  27. #define CLONE_NEWNET 0x40000000 /* New network namespace */
  28. #define CLONE_IO 0x80000000 /* Clone io context */

signal信号量定义在各个体系结构下的/arch/x/include/asm/signal.h文件中:

  1. // 向下滚动
  2. #define SIGHUP 1
  3. #define SIGINT 2
  4. #define SIGQUIT 3
  5. #define SIGILL 4
  6. #define SIGTRAP 5
  7. #define SIGABRT 6
  8. #define SIGIOT 6
  9. #define SIGBUS 7
  10. #define SIGFPE 8
  11. #define SIGKILL 9
  12. #define SIGUSR1 10
  13. #define SIGSEGV 11
  14. #define SIGUSR2 12
  15. #define SIGPIPE 13
  16. #define SIGALRM 14
  17. #define SIGTERM 15
  18. #define SIGSTKFLT 16
  19. #define SIGCHLD 17 // 标志子进程
  20. #define SIGCONT 18
  21. #define SIGSTOP 19
  22. #define SIGTSTP 20
  23. #define SIGTTIN 21
  24. #define SIGTTOU 22
  25. #define SIGURG 23
  26. #define SIGXCPU 24
  27. #define SIGXFSZ 25
  28. #define SIGVTALRM 26
  29. #define SIGPROF 27
  30. #define SIGWINCH 28
  31. #define SIGIO 29
  32. #define SIGPOLL SIGIO
  33. /*
  34. #define SIGLOST 29
  35. */
  36. #define SIGPWR 30
  37. #define SIGSYS 31
  38. #define SIGUNUSED 31
  39. /* These should not be considered constants from userland. */
  40. #define SIGRTMIN 32
  41. #define SIGRTMAX _NSIG

fork()创建进程的参数如下:

  1. clone(SIGCHLD, 0); // 发送创建子进程信号

vfork()创建进程时调用clone传递的参数如下:

  1. // 传递vfork标志,父进程准备睡眠,等待子进程发送信号唤醒
  2. // 父子共享地址空间
  3. clone(CLONE_VFORK | CLONE_VM | SIGCHLD, 0);

创建线程时调用clone传递的参数如下:

  1. // 共享地址空间,共享文件系统,共享文件描述符,共享信号处理程序
  2. clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, 0)

创建步骤分析