2022-2023-1 20222802 《Linux内核原理与分析》第七周作业

一、相关知识

1. fork()函数的理解

        一个进程调用fork()函数创建子进程时,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。
        fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。
fork()是在用户态用于创建一个子系统的系统调用。Fork()系统调用在父进程和子进程各返回一次。即:fork可以被调用一次,却能够返回两次,它可能有三种不同的返回值:
1.在父进程中,fork返回新创建子进程的进程ID;
2.在子进程中,fork返回0;
3.如果出现错误,fork返回一个负值;

       在执行fork函数后,如果新进程创建成功,则返回两个进程,一个是父进程,一个是子进程。在父进程中,fork返回新创建子进程的进程ID;在子进程中,fork函数返回0。我们可以通过输出fork返回的值来判断当前进程是子进程还是父进程。

2.fork()函数的底层实现

       Linux通过复制父进程来创建一个新进程,那么这就给我们理解这一个过程提供一个想象的框架: 

1.  复制一个PCB——task_struct

    err = arch_dup_task_struct(tsk, orig);

2.  要给新进程分配一个新的内核堆栈

    ti = alloc_thread_info_node(tsk, node);

    tsk->stack = ti;

    setup_thread_stack(tsk, orig); //这里只是复制thread_info,而非复制内核堆栈

3.  要修改复制过来的进程数据,比如pid、进程链表等等都要改改吧,见copy_process内部

        Linux通过clone()系统调用实现fork()。这个调用通过一系列的参数标志来指明父,子进程需要共享的资源。fork(),vfork()和__clone()库函数都根据各自需要的参数标志去调用clone()。然后由clone()去调用do_fork()。do_frok完成了创建中的大部分工作,它的定义在ker/frok.c文件中。该函数调用copy_process()的函数,然后让进程开始运行。copy_process()做扫尾工作并返回一个指向子进程的指针。再回到do_fork()函数,如果copy_process()函数返回成功,新创建的子进程被唤醒并让其投入运行。
 

二、实验过程

1.使用实验楼的虚拟机打开 shell

2. 下载新版本menu,在已经完成了的MenuOS里面增加一个命令fork,覆盖test.c文件

 3.使用命令make rootfs进行编译,使之生效,观察到menu中多了一个fork命令,且可以正确执行

 4.在shell1中启动内核

 5.另开一个终端,在shell2中进行gdb调试

 6.在sys_clone、do_fork、dup_task_struct、copy_process、copy_thread、ret_from_fork处设置断点

 7.使用命令“c”继续执行,gdb中continue执行到断点do_fork处

 8.继续调试,会停留在第3个断点,停在dup_task_struct函数,最终进入dup_task_struct内部,停留在copy_thread和ret_from_fork上

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值