【Linux 内核】进程管理 ( 进程相关系统调用源码分析 | fork() 源码 | vfork() 源码 | clone() 源码 | _do_fork() 源码 | do_fork() 源码 )
文章目錄
- 一、fork 系統調用源碼
- 二、vfork 系統調用源碼
- 三、clone 系統調用源碼
- 四、_do_fork 函數源碼
- 五、do_fork 函數源碼
Linux 進程相關 " 系統調用 " 對應的源碼在 linux-5.6.18\kernel\fork.c 源碼中 , 下面開始對該源碼的相關 " 系統調用 " 進行分析 ;
一、fork 系統調用源碼
fork() 系統調用函數 , 最終返回的是 _do_fork() 函數執行結果 ;
#ifdef __ARCH_WANT_SYS_FORK SYSCALL_DEFINE0(fork) { #ifdef CONFIG_MMUstruct kernel_clone_args args = {.exit_signal = SIGCHLD,};return _do_fork(&args); #else/* can not support in nommu mode */return -EINVAL; #endif } #endif二、vfork 系統調用源碼
vfork() 系統調用函數 , 最終返回的是 _do_fork() 函數執行結果 ;
#ifdef __ARCH_WANT_SYS_VFORK SYSCALL_DEFINE0(vfork) {struct kernel_clone_args args = {.flags = CLONE_VFORK | CLONE_VM,.exit_signal = SIGCHLD,};return _do_fork(&args); } #endif三、clone 系統調用源碼
clone() 系統調用函數 , 最終返回的是 _do_fork() 函數執行結果 ;
#ifdef __ARCH_WANT_SYS_CLONE #ifdef CONFIG_CLONE_BACKWARDS SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,int __user *, parent_tidptr,unsigned long, tls,int __user *, child_tidptr) #elif defined(CONFIG_CLONE_BACKWARDS2) SYSCALL_DEFINE5(clone, unsigned long, newsp, unsigned long, clone_flags,int __user *, parent_tidptr,int __user *, child_tidptr,unsigned long, tls) #elif defined(CONFIG_CLONE_BACKWARDS3) SYSCALL_DEFINE6(clone, unsigned long, clone_flags, unsigned long, newsp,int, stack_size,int __user *, parent_tidptr,int __user *, child_tidptr,unsigned long, tls) #else SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,int __user *, parent_tidptr,int __user *, child_tidptr,unsigned long, tls) #endif {struct kernel_clone_args args = {.flags = (lower_32_bits(clone_flags) & ~CSIGNAL),.pidfd = parent_tidptr,.child_tid = child_tidptr,.parent_tid = parent_tidptr,.exit_signal = (lower_32_bits(clone_flags) & CSIGNAL),.stack = newsp,.tls = tls,};if (!legacy_clone_args_valid(&args))return -EINVAL;return _do_fork(&args); } #endif四、_do_fork 函數源碼
在 _do_fork() 函數中 , 調用了 copy_process() 函數 ;
/** Ok, this is the main fork-routine.** It copies the process, and if successful kick-starts* it and waits for it to finish using the VM if required.** args->exit_signal is expected to be checked for sanity by the caller.*/ long _do_fork(struct kernel_clone_args *args) {u64 clone_flags = args->flags;struct completion vfork;struct pid *pid;struct task_struct *p;int trace = 0;long nr;/** Determine whether and which event to report to ptracer. When* called from kernel_thread or CLONE_UNTRACED is explicitly* requested, no event is reported; otherwise, report if the event* for the type of forking is enabled.*/if (!(clone_flags & CLONE_UNTRACED)) {if (clone_flags & CLONE_VFORK)trace = PTRACE_EVENT_VFORK;else if (args->exit_signal != SIGCHLD)trace = PTRACE_EVENT_CLONE;elsetrace = PTRACE_EVENT_FORK;if (likely(!ptrace_event_enabled(current, trace)))trace = 0;}p = copy_process(NULL, trace, NUMA_NO_NODE, args);add_latent_entropy();// ...return nr; }五、do_fork 函數源碼
do_fork() 函數有 555 個參數 ,
unsigned long clone_flags 參數表示 創建進程 的 標志位 集合 ;
unsigned long stack_start 參數表示 用戶空間 棧 起始地址 ;
unsigned long stack_size 參數表示 用戶空間 棧 大小 , 通常為 000 ;
int __user *parent_tidptr 參數表示 指向 用戶空間 地址的指針 , 該指針指向 父進程 的進程號 ;
int __user *child_tidptr 參數表示 指向 用戶空間 地址的指針 , 該指針指向 子進程 的進程號 ;
#ifndef CONFIG_HAVE_COPY_THREAD_TLS /* For compatibility with architectures that call do_fork directly rather than* using the syscall entry points below. */ long do_fork(unsigned long clone_flags,unsigned long stack_start,unsigned long stack_size,int __user *parent_tidptr,int __user *child_tidptr) {struct kernel_clone_args args = {.flags = (lower_32_bits(clone_flags) & ~CSIGNAL),.pidfd = parent_tidptr,.child_tid = child_tidptr,.parent_tid = parent_tidptr,.exit_signal = (lower_32_bits(clone_flags) & CSIGNAL),.stack = stack_start,.stack_size = stack_size,};if (!legacy_clone_args_valid(&args))return -EINVAL;return _do_fork(&args); } #endif
總結
以上是生活随笔為你收集整理的【Linux 内核】进程管理 ( 进程相关系统调用源码分析 | fork() 源码 | vfork() 源码 | clone() 源码 | _do_fork() 源码 | do_fork() 源码 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Linux 内核】进程管理 ( 系统调
- 下一篇: 【Linux 内核】进程管理 ( 内核线