博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
20169219linux 内核原理与分析第五周作业
阅读量:5101 次
发布时间:2019-06-13

本文共 2681 字,大约阅读时间需要 8 分钟。

进程调度

1、 进程调度是确保进程能有效工作的一个内核子进程。调度程序是像linux这样的多任务操作系统的基础。最大限度地利用处理器时间的原则是,只要有可以执行的进程,那么就总会有进程正在执行。但是只要系统中可运行的进程的数目比处理器的个数多,就注定某一给定时刻会有一些进程不能执行。

2、 多任务系统可以划分为两类:非抢占式多任务和抢占式多任务。时间片是分配给每个可运行进程的处理器时间段。有效管理时间片能使调度程序从系统全局的角度做出调度决定,这样做还可以避免个别进程独占系统资源。
3、 进程可以分为I/O消耗型和处理器消耗型。前者大部分时间用来提交I/O请求和等待I/O请求不需要长的时间片,后者时间大多用在执行代码上需要长的时间片。调度策略需要在进程响应迅速和最大系统利用率上寻找平衡。
4、 linux采用了两种不同的优先级范围。第一种是nice值,它的范围是从-20到+19,默认值为0;越大的nice值意味着更低的优先级。第二种范围是实时优先级,其值是可配置的,默认情况下它的变化范围是从0到99,越高的实时优先级数值意味着进程优先级越高。任何实时进程的优先级都高于普通进程,也就是说实时优先级和nice优先级处于互不相交的两个范畴。
可通过以下命令查案进程列表

ps-eo state,uid,pid,ppid,rtprio,time,comm

5、 时间片过长会导致系统对交互的响应表现欠佳,让人觉得系统无法并发执行应用程序;时间片太短会明显增大进程切换带来的处理器耗时,因为肯定会有相当一部分系统时间用在进程切换上,而这些进程能够用来运行的时间片却很短。

6、每个调度器都有一个优先级,基础的调度器代码定义在kernel/sched.c文件中,然后按照优先级顺序遍历调度类,决定要执行的进程。
7、 现代进程调度器的两个通用概念:进程优先级、时间片。

内核数据结构

1、链表中的元素都是动态创建并插入的,因为创建时间不同,所以内存中无须占用连续内存区。

2、链表有:单向链表、双向链表、环形单向链表、双向环形链表。
3、如果需要随机访问数据,一般不使用链表。使用链表存放数据的理想情况是,需要遍历所有数据或需要动态加入和删除数据时。
4、四种数据结构:链表、队列、映射、红黑树。

网易云课堂实验

主要了解了CPU内核源码,看了大概的结构。

cd LinuxKernel/qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img

内核启动完成后进入menu程序

执行结果如图
1028836-20161023184229248-205869011.png
使用gdb跟踪调试内核
后面一个是-s,一个是-S,用这个命令先把内核启动一下,-S表示CPU初始化之前冻结起来,-s是指1234端口上创建了一个gdb-server。
1028836-20161023184438420-182868062.png

然后就是通过gdb进行调试,首先要编译和加载带有符号表信息的目标文件。

(gdb)file linux-3.18.6/vmlinux

在gdb界面中targe remote之前加载符号表。符号表主要用来存放源程序中的各种有用的信息。包括:变量名、目标地址、类型等。在编译各个阶段需要对这些信息进行访问、增加和更新。

(gdb)target remote:1234

建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行

(gdb)break start_kernel

gdb和server之间的关系如图所示(通过1234这个端口建立连接):

1028836-20161220192351245-1469451563.jpg

设置断点

1028836-20161212123118917-187190813.png

1028836-20161212123306698-2136008046.png

1028836-20161212123038323-1670315223.png

下面分析一下代码,了解内核的启动过程

393static noinline void __init_refok rest_init(void)394{395 int pid;396397 rcu_scheduler_starting();398 /*399  * We need to spawn init first so that it obtains pid 1, however400  * the init task will end up wanting to create kthreads, which, if401  * we schedule it before we create kthreadd, will OOPS.402  */403 kernel_thread(kernel_init, NULL, CLONE_FS);404 numa_default_policy();405 pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);406 rcu_read_lock();407 kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);408 rcu_read_unlock();409 complete(&kthreadd_done);410411 /*412  * The boot idle thread must execute schedule()413  * at least once to get things moving:414  */415 init_idle_bootup_task(current);416 schedule_preempt_disabled();417 /* Call into cpu_idle with preempt disabled */418 cpu_startup_entry(CPUHP_ONLINE);419}

这里面包含了三个进程idle,kernel_init,kthreadd。

其中idle进程(PID = 0), kernel_init进程(PID = 1),kthreadd(PID = 2)

kernel_init是所有用户态进程的祖先,kthreadd是所有内核线程的祖先。
三个进程之间的关系

  • idle进程由系统自动创建, 运行在内核态;
  • kernel_init进程由idle通过kernel_thread创建,在内核空间完成初始化后, 加载init程序, 并最终返回到用户空间;
  • kthreadd进程由idle通过kernel_thread创建,并始终运行在内核空间, 负责所有内核线程的调度和管理;

转载于:https://www.cnblogs.com/weihua2616/p/5990578.html

你可能感兴趣的文章
五分钟搭建WordPress博客(二)
查看>>
Vue_(组件通讯)子组件向父组件传值
查看>>
jvm参数
查看>>
Something-Summary
查看>>
Spring学习笔记
查看>>
6个有用的MySQL语句
查看>>
linux c/c++ IP字符串转换成可比较大小的数字
查看>>
我对前端MVC的理解
查看>>
sql: table,view,function, procedure created MS_Description in sql server
查看>>
[网络流24题] 最长k可重区间集问题 (费用流)
查看>>
ActiveX多线程回调JavaScript
查看>>
剑指offer系列32-----对称二叉树的判断
查看>>
Silverlight实用窍门系列:19.Silverlight调用webservice上传多个文件【附带源码实例】...
查看>>
2016.3.31考试心得
查看>>
Python 编程快速上手 第 7章 模式匹配与正则表达式
查看>>
c#FTP应用---windows iis
查看>>
linux下调整java版本
查看>>
AutoCAD实用技巧基础篇
查看>>
Junit测试工具
查看>>
ubuntu 系统环境配置记录
查看>>