理论

  1. task_struct的结构关系

    非常庞大的数据结构,400多行代码。包括对进程链表的管理,控制台,文件系统描述,文件描述符,内存管理描述,信号描述等。

  2. 创建一个新进程在内核中的执行过程

    fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建;Linux通过复制父进程来创建一个新进程,那么这就给我们理解这一个过程提供一个想象的框架:

    复制一个PCB——task_struct
err = arch_dup_task_struct(tsk, orig);

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

ti = alloc_thread_info_node(tsk, node);
tsk->stack = ti;
setup_thread_stack(tsk, orig); //这里只是复制thread_info,而非复制内核堆栈

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

从用户态的代码看fork();函数返回了两次,即在父子进程中各返回一次,父进程从系统调用中返回比较容易理解,子进程从系统调用中返回,那它在系统调用处理过程中的哪里开始执行的呢?这就涉及子进程的内核堆栈数据状态和task_struct中thread记录的sp和ip的一致性问题,这是在哪里设定的?copy_thread in copy_process

1 *childregs = *current_pt_regs();   //复制内核堆栈
2 childregs->ax = 0; //为什么子进程的fork返回0,这里就是原因!
3
4 p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶
5 p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址

实验(使用gdb跟踪创建新进程)

fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建,do_fork完成了创建中的大部分工作。

具体分析过程如下:

cd LinuxKernel
ls
cd menu
vi test.c

在这里与上次实验一样,仍然使用不了git clone这样的命令,于是自己进入menu目录下,对立面的test.c进行修改,修改如下:

#include <unistd.h>  //添加头文件到文件中

int Fork(int argc, char *argv[])  //添加一个新的函数Fork()
{
int pid;
/* fork another process */
pid = fork(); //fork之后变为两个进程
if (pid<0)
{
/* error occurred */
fprintf(stderr,"Fork Failed!");
exit(-1);
}
else if (pid==0) //子进程中fork的返回值为0
{
/* child process */
printf("This is Child Process!\n");
}
else
{
/* parent process */
printf("This is Parent Process!\n"); //父进程中fork的返回值为子进程的ID
/* parent will wait for the child to complete*/
wait(NULL);
printf("Child Complete!\n");
}
}
通过这个小程序,可以在用户态创建一个子进程。
//main函数中需要加入:
MenuConfig("fork","Fork a new process",Fork);

保存并退出。

在menu目录下make rootfs便可编译,成功启动MenuOS系统,输入help可以看到如图所示的效果

接下来要使用gdb来跟踪调试进程创建过程,所以需要设置断点。

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage initrd rootfs.img -s -S
gdb
file linux-3.18.6/vmlinux //加载内核
target remote:1234 //链接到menu os里

分别在sys_clone,do_fork,dup_task_struct,copy_process,copy_thread,ret_from_fork这几处设置断点,如图

当按c继续执行之后,后面的断点依次如图所示

图4中出现了 copy_process

再继续跟踪可以看到如下

问题:

新进程从哪里开始执行?

回答:ret_from_fork决定了新进程的第一条指令地址:

p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址

总结:

  1. Linux通过复制父进程来创建一个子进程,通过调用fork来实现;
  2. Linux会为每个子进程动态的分配一个task_struct结构;
  3. Linux用双向循环链表的方式来组织系统中的所有进程(包括内核线程)
  4. fork()函数被调用一次,但返回两次

书上内容

  1. 时钟中断的工作:跟新系统运行时间;跟新实际时间;在SMP系统中均衡调度各处理器的运行列队;检查当前进程是否耗尽时间片,若耗尽则进行重新调度;运行超时的动态定时器;更新资源消耗和处理器时间的统计值。提高HZ的优点:更高时钟中断解析度;提高时间驱动事件的准确性(平均误差5ms->0.5ms);内核定时器能够以更高的频度和更高准确度执行;依赖定时器的系统调用(如poll和select)能以更高精度运行;对资源消耗和系统运行时间的测量更准确;提供进程抢占的准确度。
  2. 定时器是管理内核流逝的时间的基础。使用很简单,执行一些初始化的工作,设置一个超时时间,指定超时发生后执行的函数,然后激活定时器就可以了。定时器与当前执行代码是异步的,因此就有可能存在潜在的竞争条件。
  3. 内核把物理页作为内存管理的基本单位;区:ZONE_DMA:包含的页用来执行DMA操作;ZONE_NORMAL:正常映射的页;ZONE_HIGHMEM:“高端内存”(并不能永久映射到内核地址空间);释放页:void __free_pages(struct page *page, unsigned int order); void free_pages(unsigned long addr, unsigned int order); void free_page(unsigned long addr)。gfp_mask该标志可以分为三类:(1)行为修饰符:描述内核如何分配所需内存。(2)区修饰符:从哪个区分配内存。(3)类型:组合了行为和区修饰符,提供了常用的标志。
  4. 使用每个cpu数据具有不少好处。首先是减少了数据锁定,第二是使用每个cpu数据可以大大减少缓存失效。目前并不要求必须使用每个cpu的新接口,新接口并不向后兼容之前的内核。

20169212《Linux内核原理与分析》第八周作业的更多相关文章

  1. 20169212《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...

  2. 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...

  3. 20169210《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...

  4. 2017-2018-1 20179215《Linux内核原理与分析》第二周作业

    20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...

  5. 2019-2020-1 20199329《Linux内核原理与分析》第九周作业

    <Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...

  6. 2019-2020-1 20199329《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...

  7. 2019-2020-1 20209313《Linux内核原理与分析》第二周作业

    2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...

  8. 2018-2019-1 20189221《Linux内核原理与分析》第一周作业

    Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...

  9. 《Linux内核原理与分析》第一周作业 20189210

    实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...

  10. 2020-2021-1 20209307 《Linux内核原理与分析》第九周作业

    这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)> 这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第九周作业> 这个作业的目标 & ...

随机推荐

  1. windows系统nginx配置root绝对路径的问题

    看了下logs下面的error.log文件,发现路径有问题,修改了conf配置,把root的路径反斜杠要用两个反斜杠进行转义,再次运行正常了.

  2. ResultSet相关ResultSetMetaData详细

    DatabaseMetaData 有关整个数据库的信息:表名.表的索引.数据库产品的名称和版本.数据库支持的操作. ResultSet 关于某个表的信息或一个查询的结果.您必须逐行访问数据行,但是您可 ...

  3. [OSG]矩阵运算

    我们都知道,OpenGL规定矩阵使用列主序存储,即glLoadMatrix等函数要求输入的数组是按列主序存储的矩阵.然而,一个很奇怪的事实是,OSG中矩阵存储是使用的标准C二维数组(行主序),并且也是 ...

  4. 分析恶意windows程序

    1.windows 注册表 注册表根键 注册表被划分为下面5个根键 HKEY_LOCAL_MACHINE(HKLM) 保存对本地机器全局设置 HKEY_CURRENT_USER(HKCU) 保存当前用 ...

  5. MySQL之alter语句用法总结

    MySQL之alter语句用法总结 1:删除列 ALTER TABLE [表名字] DROP [列名称] 2:增加列 ALTER TABLE [表名字] ADD [列名称] INT NOT NULL  ...

  6. RabbitMQ 入门 Helloworld

    1.介绍 RabbitMQ 是信息传输的中间者.本质上,他从生产者(producers)接收消息,转发这些消息给消费者(consumers).换句话说,他能够按根据你指定的规则进行消息转发.缓冲.和持 ...

  7. windows系统中WIN键的快捷组合

    1.WIN+E    打开我的电脑(计算机) 2.WIN+D      返回桌面 当你在用聊天工具与朋友聊天时,旁边突然出现某位小伙伴,快速按下WIN+D返回到桌面就可以很好的保护你的聊天内容啦! 3 ...

  8. Spark学习(四) -- Spark作业提交

    标签(空格分隔): Spark 作业提交 先回顾一下WordCount的过程: sc.textFile("README.rd").flatMap(line => line.s ...

  9. 30.Nginx集群搭建笔记

    源码安装Nginx: tar -zxvf nginx-1.8.0.tar.gz -C /nginx/        #解压Nginx rpm -ivh keepalived-1.2.13-5.el6_ ...

  10. SpringMVC和MyBatis整合

    目前主流的Web MVC框架,除了Struts这个主力 外,还有Spring MVC,主要是由于Spring MVC配置比较简单,使用起来也十分明了,非常灵活,与Spring 集成较好,对RESTfu ...