fork源码剖析

fork是复制进程,那么首先要清楚进程是什么?

 进程是一个正在运行的程序,是资源分配的最小单位,系统管理进程是依靠对进程控制块(PCB)的管理完成的,每个进程的产生分两步,一是:分配PCB,二是准备进程实体,如分配内存空间等。

fork() 创建进程,1、fork()调用一次,返回2次,子进程的返回值是0,父进程的返回值是新子进程的进程ID。 2、文件共享 在fork之前父进程打开的文件子进程才能使用,一个进程打开的文件描述符是在PCB中记录的,父进程调用fork()创建子进程的过程中,子进程的PCB是拷贝父进程的PCB,父进程的所有打开的文件描述符都被复制到子进程中。父子进程每个相同的打开描述符共享一个文件表项。文件描述符的引用计数count+1,不仅如此,父进程的用户根目录、当前工作目录等变量的引用计数均+1

pthread_creat()创建线程

 vfork()创建一个新进程,子进程去调用exec,并不将父进程的地址空间完全复制到子进程中去,因为子进程会立即调用exec(或者exit),于是就不会访问该地址空间并保证子进程先运行,直到子进程调用exec或者exit子后,父进程才会运行。

 fork() ,pthread_creat(), vfork()的系统调用分别是sys_fork(),sys_clone(), sys_vfork(),它们的底层都用的是do_fork(),只是传的参数,和标志不同

我们对sys_fork()的do_fork()转到定义:

do_fork():1、定义PCB指针struct task_struct *p; 2、分配PID,cat /proc/sys/kernel/pid_max命令可以查看一个系统支持的最大进程数,进程数的范围0~32768,理论值。 3、调用copy_process方法,创建子进程的task_struct.

copy_process(),完成创建子进程的PCB

  1、分配PCB,继承父进程的PCB中的值,只是将特有的信息改过来。每个进程都有task_thread,thread_info结构体保存的是进程上下文的信息。要修改thread_info *info,子进程的task_struct的成员struct thread_info *info指向自己的struct thread_info,而且struct thread_info结构体的成员struct task_struct *p指向子进程自己的struct task_struct.即下面代码用红色标记的部分。

2、其中copy_files()复制父进程打开的文件描述符

3、其中copy_mm()复制地址空间,struct mm_struct *mm,*active_mm, mm表示:进程所拥有的内存空间的描述符,对于内核线程的mm为NULL,active_mm表示:进程运行时所使用的进程描述符。

       1、判断是否设置了CLONE_VM标志,如果设置,创建线程,新线程共享父进程的地址空间,将mm_users加1,然后mm=oldmm,把父进程的mm_struct指针赋给子进程的mm_struct.

                      如果没有设置,当前进程分配一个新的内存描述符,mm=allocate_mm(),  将它的地址放在子进程的mm中。再把父进程(*oldmm)的内容拷进(*mm)中

     2、dup_mmap(mm, oldmm)

        复制线性区和页表,设置mm的一些属性,改变父进程的私有,可写的页为只读的,以使写时拷贝技术生效。

4、除此之外,我们还要复制父进程的内核栈,copy_thread()

   调用copy_thread,用发出clone系统调用时CPU寄存器的值(它们保存在父进程的内核栈中)
   来初始化子进程的内核栈。不过,copy_thread把eax寄存器对应字段的值(这是fork和clone系统调用在子进程中的返回值)
   强行置为0。子进程描述符的thread.esp字段初始化为子进程内核栈的基地址。ret_from_fork的地址存放在thread.eip中。
   如果父进程使用IO权限位图。则子进程获取该位图的一个拷贝。
   最后,如果CLONE_SETTLS标志被置位,则子进程获取由CLONE系统调用的参数tls指向的用户态数据结构所表示的TLS段。

    这就是为什么父子进程沿着统一位置执行,以及子进程的返回值是0。

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值