fork注意事项

1.Linux中进程的创建方式(系统调用: fork、clone、vfork)

(1)fork()(不带参数)和clone()(带参数): 这两者的区别在于fork()是全部复制而clone()则可以将资源有选择的复制给子进程,而没有复制的数据结构则是通过指针的复制让子进程共享,极端情况下一个进程可以clone()出一个线程。所以系统调用fork()无参数,而clone()则带有参数

(2)vfork()(也不带参数):但是vfork除了task_struct结构和系统堆栈以外的资源全部都要通过数据结构的复制来遗传,所以vfork()创建出来的是线程而不是进程

(3)这三个底层都是调用do_fork实现不同的只有参数

2.Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程,这个结构体包含了一个进程所需的所有信息

current宏:查找到当前正在运行的进程描述符

3.有的硬件体系结构可以拿出一个专门的寄存器来存放指向当前进程task_struct的指针,用以加快访问速度但是像x86这样的结构体系地址寄存器并不富余,就只能在内核栈的尾端创建thread_info结构,通过计算偏移间接的查找task_struct结构

copy_thread():就是在fork中只复制父进程的系统空间堆栈的函数


   系统空间堆栈的尾端:当一个进程因为系统调用或中断进入内核时,其系统空间堆栈的顶部保存这CPU进入内核前夕各个寄存器的内容,并形成一个pt_regs数据结构
   pt_regs在内核栈的顶部,通过struct task_struct中的thread_info指针到内核栈最底部加THREAD_SIZE-1将它放在内核栈最顶部

4.进程是处于执行期的程序以及它所管理的资源(如打开的文件、挂起的信号、进程状态、地址空间等等)的总称。注意的是,程序并不是进程,实际上两个或者多个进程不仅有可能执行同一程序,而且还有可能共享地址空间。

5.

(1)Linux允许用户使用一个叫做进程标识符process ID(pid)的数来标识进程,PID存放在进程描述符的pid字段。

(2)内核中使用位图来管理这些pid,由于使用内嵌的汇编语言扫描位图(pidmap-arra位图),所以效率较高,数据结构为pidmap-array,内核使用页框来存放位图,一个页框包含32768个位,所以32位体系结构中pidmap-array位图存放在一个单独的页中。然而,在64位体系结构中,可能需要为PID位图增加更多的页,

(3)在2.6内核中,进程中最大的进程pid32768,但是不考虑内存等因素制约,不超过一个整型数(int)所表示的数的大小

(4)首先是last pid加1作为新进程的pid,如果pid大于等于pid_max,就把pid置为RESERVED_PIDS(300),从RESERVED_PIDS开始查找空闲pid,然后获取页内偏移和该pid所对应的pidmap结构体,)接下来会通过一个for循环来遍历位图,max_scan表明遍历次数,如果offset为0,即从0开始查找空闲pid,max_scan为0,那么只需要遍历一次;如果offset不为0,max_scan为1,需要遍历二次。

(5)32位体系结构上,pid位图是一个物理页,但是pid的值可以超过一页含有的位数32768,

6.在fork时,新进程的内核栈是通过alloc_thread_info宏获取一块空闲内存区用来存放thread_info结构和内核栈。这块内存区字段的大小是8k或4k

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值