Fork底层代码

Linux是抢占多任务操作系统。

使用 uname -a 可以查看版本信息

 进程在她被创建的时刻开始存活。在Linux系统中,这通常是调用Fork()系统调用的结果。该系统通过调用复制一个现有进程来创建一个全新的进程。调用Fork()的进程被称为父进程,新产生的进程被称为子进程。在该调用结束时,在返回点这个相同位置上,父进程恢复执行,子进程开始执行。fork()系统调用从内核返回两次:一次回到父进程,另一次回到新诞生的子进程。最终,系统通过调用exit()系统调用结束进程。

内核通过一个唯一的进程标识值或PID来标识每一个进程。PID是一个数,表示为pid_t隐含类型,实际上就是一个int类型。为了与老版本的Unix和Linux系统兼容,PID最大默认值设置为32768(short int 短整型的最大值)。尽管这个值也可以增加到类型所允许的范围。内核把每个进程的PID放在它们各自的进程描述符中。这个最大值很重要。因为它实际上就是系统中允许同时存在的进程的最大数目。

使用cat /proc/sys/kernel/pid_max来查看目前系统默认能够运行的进程数目。

 

在内核中,访问任务通常需要获得指向其task_struct指针。实际上,内核中大部分处理进程的代码都是直接通过task_struct进行的。因此通过current宏 查找到当前正在运行进程的进程描述符的速度就显得尤为重要。

Linux通过clone()系统调用实现fork()。这个调用通过一系列的参数标志来指明父子进程需要共享的资源。fork()、vfork()、和_clone()库函数都是根据各自需要的参数标志去调用clone()然后由clone()去调用do_fork

转到do_fork定义

 分配pid

分配task_struct,thread_info,内核栈

最后将父进程的时间分一半给子进程,状态设为就绪

 

 

 

复制地址空间

fork的整个过程

       调用get_ pid()为新进程获取一个有效的PID。

       调用dup_ task struct()为新进程创建-一个内核栈、thread_ info结 构和task_ struct, 这些值与当前进程的值相同。此时,子进程和父进程的描述符是完全相同的。

       检查新创建的这个子进程后,当前用户所拥有的进程数目没有超出给他分配的资源的限制。现在,子进程着手使自己与父进程区别开来。进程描述符内的许多成员都要被清0或设为初始值。进程描述符的成员值并不是继承而来的,而主要是统计信息。进程描述符中的大多数数据都是共享的。

       接下来,子进程的状态被设置为TASK UNINTERRUPTIBLE以保证它不会投人运行。

      copy_process()调用copy_ flags()以更新task struct的flags成员。表明进程是否拥有超级用户权限的PF_ SUPERPRIV标志被清0。表明进程还没有调用exec()函数的PF_ FORKNOEXEC标志被设置。
      根据传递给clone()的参数标志,copy_ process<)拷贝或共享打开的文件,文件系统信息、信号处理函数、进程地址空间和命名空间等。在一般情况下,这些资源会被给定进程的所有线程共享;否则,这些资源对每个进程是不同的,因此被拷贝到这里。让父进程和子进程平分剩余的时间片(第4章将作具体讨论)。最后,copy_ process()作扫尾工作并返回一个指向子进程的指针。(《LINUX内核设计与实现》)
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值