fork源码分析

fork的整体流程

  1. 当用户空间的代码调用fork的时候,产生0x80号中断。(此时用户空间的程序阻塞,保存用户空间的上下文信息,进入内核程序)
  2. system_call处理0x80号中断程序,获取用户空间通过寄存器带来的系统调用号
  3. 内核程序通过系统调用号,调用对应的系统调用函数sys_fork()
  4. sys_fork()底层通过do_fork()实现,调用内核代码do_fork()
  5. 首先do_fork()向系统申请一个pid,标识新产生的子进程
    (pid 的最大值32768 开始申请时在当前进程的最大的pid的基础上加一,
    当超过最大值的时候,从开始设置的起始位置找第一个可以使用的pid)
  6. 分配进程的pcb块
    slab 分配器会为内核中经常用到的一些数据结构构造专用的高速缓存区,使得提高内存的分配效率
    alloc_task_struct(); 宏可以申请一个pcb块大小的内存块
  7. 分配内核栈 thread_info
    在task_struct结构体中,有一个指针指向一块内核栈的空间,这块空间中存储着内核进程的调用信息
  8. 复制父进程的pcb块与内核栈的信息
    *ti = *orig->thread_info; //将父进程的进程的描述信息复制到新申请的thread_info结构体中
    *tsk = *orig; //父进程的pcb块复制到新申请的task_struct结构体中,该复制属于浅拷贝,所以要有前一句的复制过程
    tsk->thread_info = ti; //新申请的pcb块中的thread_info 指向新申请的内核栈
    ti->task = tsk; //新申请的内核栈中的task指针指向新申请的pcb块
  9. 保存新进程的pid
    在 task_struct 中的pid的值设置为刚刚申请的pid的值
  10. 复制父进程的各种信息
		/**
		 * copy_semundo,copy_files,copy_fs,copy_sighand,copy_signal
		 * copy_mm,copy_keys,copy_namespace创建新的数据结构,并把父进程相应数据结构的值复制到新数据结构中。
		 * 除非clone_flags参数指出它们有不同的值。
		 */
		if ((retval = copy_semundo(clone_flags, p)))
			goto bad_fork_cleanup_audit;
		//文件描述符
		if ((retval = copy_files(clone_flags, p)))
			goto bad_fork_cleanup_semundo;
		//文件系统
		if ((retval = copy_fs(clone_flags, p)))
			goto bad_fork_cleanup_files;
		if ((retval = copy_sighand(clone_flags, p)))
			goto bad_fork_cleanup_fs;
		if ((retval = copy_signal(clone_flags, p)))
			goto bad_fork_cleanup_sigh
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值