版权声明:本文为博主原创文章,未经博主允许不得转载。 罗军 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
进程在内核态运行时需要自己的堆栈信息,linux内核为每个进程都提供了一个内核栈。对每个进程,Linux内核都把两个不同的数据结构紧凑的存放在一个单独为进程分配的内存区域中:
它们共同组成了thread_union
union thread_union
{
struct thread_info thread_info;
unsigned long stack[THREAD_SIZE/sizeof(long)];
};
task_struct包含了指向thread_info的字段,而thread_info通过task字段和thread_struct相互联系。
写时复制技术允许父子进程读相同的物理页,只要两者中有一个试图写一个物理页,内核就把这个页的内容拷贝到一个新的物理页,并把这个新的物理页分配给正在写的进程。这样做得目的是为了提高进程创建的效率,因为子进程全部拷贝父进程的地址空间非常慢且效率低,实际上,子进程几乎不必读或修改父进程拥有的所有资源,在很多情况下,子进程立即调用execve(),并清除父进程之前拷贝过来的地址空间。 这里为什么要介绍写时复制呢? 因为wake_up_new_task函数里会执行下列操作:如果子进程和父进程运行在同一个CPU上,而且父进程和子进程不能共享同一组页表,那么,就把子进程插入父进程运行队列,插入时让子进程在父进程前面执行,这里为什么要让子进程先执行呢? 因为如果我们先让父进程运行,那么写时复制机制将会执行一系列不必要的页面复制。
if (!(clone_flags & CLONE_UNTRACED)) {
if (clone_flags & CLONE_VFORK)
trace = PTRACE_EVENT_VFORK;
else if ((clone_flags & CSIGNAL) != SIGCHLD)
trace = PTRACE_EVENT_CLONE;
else
trace = PTRACE_EVENT_FORK;
if (likely(!ptrace_event_enabled(current, trace)))
trace = 0;
}
从上面的代码可以看出系统调用clone()、fork()、和vfork()都是由do_fork()进行处理的。do_fork通过copy_process函数来创建进程描述符和子进程执行所需要的所有其他内核数据结构。
dup_task_struct 根据父进程创建子进程内核栈和进程描述符:
static struct task_struct *dup_task_struct(struct task_struct *orig)
{
struct task_struct *tsk;
struct thread_info *ti;
int node = tsk_fork_get_node(orig);
int err;
//创建进程描述符对象
tsk = alloc_task_struct_node(node);
if (!tsk)
return NULL;
//创建进程内核栈
ti = alloc_thread_info_node(tsk, node);
if (!ti)
goto free_tsk;
//使子进程描述符和父进程一致
err = arch_dup_task_struct(tsk, orig);
if (err)
goto free_ti;
//进程描述符stack指向thread_info
tsk->stack = ti;
……
//使子进程thread_info内容与父进程一致但task指向子进程task_struct
setup_thread_stack(tsk,orig);
……
return tsk;
……
}
forkAPI函数,会通过宏指令来跳转到相应的系统调用
forkAPI函数会通过SYS_clone宏指令,最终会调用do_fork函数:
调用copy_process函数
调用dup_task_struct函数
经过dup_task_struct和copy_thread等一系列操作后,子进程被创建,递增总进程数: 创建子进程之前total_forks值:
创建子进程之后total_forks值:
进程上下文的切换:
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有