2、do_fork 流程
调用 copy_process 为子进程复制出一份进程信息 如果是 vfork 初始化完成处理信息 调用 wake_up_new_task 将子进程加入调度器,为之分配 CPU 如果是 vfork,父进程等待子进程完成 exec 替换自己的地址空间3、copy_process 流程
追踪copy_process 代码(部分)
static struct task_struct *copy_process(unsigned long clone_flags,
unsigned long stack_start,
unsigned long stack_size,
int __user *child_tidptr,
struct pid *pid,
int trace)
{
int retval;
//创建进程描述符指针
struct task_struct *p;
//……
//复制当前的 task_struct
p = dup_task_struct(current);
//……
//初始化互斥变量
rt_mutex_init_task(p);
//检查进程数是否超过限制,由操作系统定义
if (atomic_read(&p->real_cred->user->processes) >=
task_rlimit(p, RLIMIT_NPROC)) {
if (p->real_cred->user != INIT_USER &&
!capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN))
goto bad_fork_free;
}
//……
//检查进程数是否超过 max_threads 由内存大小决定
if (nr_threads >= max_threads)
goto bad_fork_cleanup_count;
//……
//初始化自旋锁
spin_lock_init(&p->alloc_lock);
//初始化挂起信号
init_sigpending(&p->pending);
//初始化 CPU 定时器
posix_cpu_timers_init(p);
//……
//初始化进程数据结构,并把进程状态设置为 TASK_RUNNING
retval = sched_fork(clone_flags, p);
//复制所有进程信息,包括文件系统、信号处理函数、信号、内存管理等
if (retval)
goto bad_fork_cleanup_policy;
retval = perf_event_init_task(p);
if (retval)
goto bad_fork_cleanup_policy;
retval = audit_alloc(p);
if (retval)
goto bad_fork_cleanup_perf;
/* copy all the process information */
shm_init_task(p);
retval = copy_semundo(clone_flags, p);
if (retval)
goto bad_fork_cleanup_audit;
retval = copy_files(clone_flags, p);
if (retval)
goto bad_fork_cleanup_semundo;
retval = copy_fs(clone_flags, p);
if (retval)
goto bad_fork_cleanup_files;
retval = copy_sighand(clone_flags, p);
if (retval)
goto bad_fork_cleanup_fs;
retval = copy_signal(clone_flags, p);
if (retval)
goto bad_fork_cleanup_sighand;
retval = copy_mm(clone_flags, p);
if (retval)
goto bad_fork_cleanup_signal;
retval = copy_namespaces(clone_flags, p);
if (retval)
goto bad_fork_cleanup_mm;
retval = copy_io(clone_flags, p);
//初始化子进程内核栈
retval = copy_thread(clone_flags, stack_start, stack_size, p);
//为新进程分配新的 pid
if (pid != &init_struct_pid) {
retval = -ENOMEM;
pid = alloc_pid(p->nsproxy->pid_ns_for_children);
if (!pid)
goto bad_fork_cleanup_io;
}
//设置子进程 pid
p->pid = pid_nr(pid);
//……
//返回结构体 p
return p;
调用 dup_task_struct 复制当前的 task_struct








