前言

应用层通常专注于API的使用,认为将其看成是一个黑盒即可,但了解操作系统的一些机制将有助于我们更好地使用它,也有助于避免犯错误。

unix系统

1969年,unix从贝尔实验室诞生,由一个失败的操作系统multics发展而来,它发布时带上了源码,以至于很多组织都对其进一步改进。它由C语言编写,且只有几百个系统调用,秉承一切皆文件的设计思想。

linux系统

由芬兰大学生linus在1991年开发,基于Intel80386微处理器,开发完后就在因特网发布了源码。它借鉴了unix的很多设计思想,但它的实现完全不同,算是一个不同的操作系统。开源协议非常自由,可以自由修改,但需要将改过的源码继续发布出来。

linux特点

  • 它是单内核,与之相反的是微内核。
  • 模块化设计,支持动态加载内核模块。
  • 支持对称多处理机制(SMP),多个处理器需要考虑共享资源问题。
  • 抢占式多任务操作系统,内核对进程的调度属于抢占式。
  • 支持内核线程,但它不区分线程与进程,对他来说所有进程都一样。

什么是操作系统

操作系统负责最基本的功能和系统管理,包括内核、设备驱动、启动引导、shell、界面、文件管理、其它系统工具。应用程序通常通过库函数,库函数通过系统调用让内核去完成各种任务。

CPU活动状态

  • 运行于用户空间,执行用户进程。
  • 运行于内核空间,处于进程上下文,表示执行某个进程。
  • 运行于内核空间,处于中断上下文,此时与任务进程都无关,它在处理某个中断。

进程&线程

进程是处于执行期的程序,它包含各种资源,比如文件、信号、内核数据、处理器状态、内存空间、执行线程、全局数据段等。进程提供了虚拟处理器和虚拟内存,看起来进程就像自己独享相应资源。

内核将所有进程保存在任务队列中,它是一个双向循环链表,该链表中每个节点的类型都是task_struct进程描述符结构,处于中。

所有进程都是PID为1的init进程的后代,内核启动的最后阶段启动init进程,它负责读取系统的初始化脚本并执行其它相关程序。每个进程都有一个父进程,每个进程也都可以有零个或多个子进程。fork()用于创建子进程,它通过拷贝当前进程来创建一个子进程,父子进程区别在于PID、PPID、某些资源、统计量不同。fork()使用了写时拷贝机制,父进程和子进程共享同一个拷贝,只有需要写入时数据才会被复制。fork()的实际开销就是复制父进程的页表以及给子进程创建唯一进程描述符。exec()负责读取可执行文件并将其载入空间开始运行。进程调用exit()系统调用时进程被终结。

线程是进程的活动对象,每个线程都拥有独立的程序计数器、进程栈和一组寄存器。线程能在同一程序里面共享内存地址空间,共享文件和其它资源。从内核角度来说linux并没有线程这个概念,它将线程当成是进程来看待。内核线程没有独立的地址空间,只运行在内核空间,从不切换到用户空间。

进程的调度

进程调度器的目的就是最大限度地利用CPU时间,只要有可执行的任务就要尽量去执行它们,但我们知道系统中几乎总是任务数大于处理器个数,所以肯定某个时刻有任务得不到执行。多任务系统能并发地执行多个进程,一个CPU时是一对多,多个CPU时是多对多,所有任务看起来就像是同时在运行一样。

多任务系统分为抢占式和非抢占式,linux是抢占式调度,调度程序来决定进程的挂起和执行,每个进程能执行的时间为时间片,现代系统一般都有一定的策略来动态分配时间片。非抢占式则是由进程自己主动停止,否则将一直运行下去,调度程序无法决定进程的运行停止,如果某个进程一直运行则会使系统奔溃。

调度策略

进程可分为I/O密集型和处理器密集型。前者大部分时间进行各种I/O请求,通常这些进程只运行很短一段时间,然后就在I/O上阻塞了。而后者则是大部分时间都用于代码执行上,不停地运行而且没有什么I/O请求。当然有些进程既是I/O密集型也是处理器密集型。对于前者我们希望时间片少一点,对于后者我们希望时间片多一点,调度策略就是要在两个矛盾中找到平衡,使得进程能够响应迅速又能最大系统利用率。

基于优先级的调度是最基本的一种调度算法,它把进程进行了分级,优先级高的先运行,优先级低的后运行,相同优先级的进程则轮流运行。某些系统中优先级高的进程将更频繁运行,且时间片也更长。调度程序选择时间片未用尽且优先级最高的进程来执行。linux有两种优先级范围,第一种是nice值,从-20到+19,默认为0,值越大优先级越低。第二种是实时优先级,默认范围是0到99,值越高表示优先级越高。任何实时进程的优先级都高于普通进程,也就是说nice优先级和实时优先级是两个不同维度。

时间片是进程在被抢占前所能持续运行的时间,默认的时间片大小不容易确定,时间片太长会使交互响应变差,时间片太短会增加进程切换带来的损耗。也就是前面说到的矛盾,I/O密集型希望时间片短点,而处理器密集型则希望时间片长点。

CFS调度器

linux采用了完全公平调度(CFS)算法,它是一个针对普通进程的调度器,linux中称为SCHED_NORMAL,而POSIX则称为SCHED_OTHRER,实现类在kernel/sched_fair.c中。CFS允许每个进程运行一段时间、循环轮转、选择运行最少的进程作为待运行进程,CFS计算所有可运行进程总数作为基础,再计算一个进程应该运行多久,而不是靠优先级来计算时间片。CFS有一个最小时间片(最小粒度),默认是1ms。也就是说就算有无穷大个进程,每个进程最少也能有1ms时间片。CFS确保给每个进程公平的处理器使用比。

  • CFS不再简单使用时间片的概念,而是必须要维护每个进程运行的时间记账,以此确保每个进程公平分配。
  • CFS选择下一个待运行进程时它会挑一个具有最小运行时间的进程。
  • 睡眠(被阻塞)的进程处于不可执行状态,它将从可执行红黑树中移除,放到等待队列中。等待队列是简单链表结构,
  • 唤醒,与睡眠刚好相反,进程被设置为可执行状态,并且从等待队列中移到可执行红黑树中。
  • 上下文切换,即从一个可执行线程切换到另一个可执行进程,由kernel/sched.c的context_switch函数负责。将虚拟内存从上一个进程映射到新进程,保存恢复栈信息和寄存器信息以及其它相关信息。
  • 内核提供了need_resched标志来表明是否需要重新执行一次调度,内核无论是咋中断处理程序还是在系统调用后返回都会检查这个歌表示,如果被设置了则内核会选择一个更适合的进程投入运行。

实时调度

linux提供了两种实时调度策略:SCHED_FIFO和SCHED_RR。前者是一种简单的先入先出调度算法,它不使用时间片。处于SCHED_FIFO级别的进程会比任何SCHED_NORMAL级别的进程先得到调度。一旦某个SCHED_FIFO级别的进程处于可执行状态,它将会一直执行,直到它自己阻塞或显示释放CPU。只有更高优先级的SCHED_FIFO或SCHED_RR进程才能抢占它。两个相同优先级的SCHED_FIFO级别的进程会轮流执行,其它普通进程只能等它变为不可运行状态后才有机会执行。

SCHED_RR大致与SCHED_FIFO相同,但它是耗尽事先分配的时间后就不再继续执行,即SCHED_RR是带了时间片的SCHED_FIFO。时间片只是相对于同一优先级的进程,低优先级的进程无法抢占SCHED_RR任务,即使它的时间片耗尽也不行。

放弃处理器时间

linux 通过sched_yield()系统调用来放弃当前进程的处理器时间,让给其他待执行进行,对于实时进程,它会将进程从活动队列中移到其优先级队列的后面。早期linux的yield语义不一样,只会将进程放到优先级队列的末尾,放弃的时间不会太长。

linux yield_linux内核的一些知识点(上)相关推荐

  1. windows上linux内核的移植,大神着手为M1 Mac原生移植Linux:内核之父曾放言不可能完成...

    在M1 Mac上运行Windows程序已经有了不少方法,包括使用付费软件CrossOver.借助QEMU模拟运行Windows 10等,知名软件Parallels也在适配中. 不过由于苹果的BootC ...

  2. linux 套接口文件_继上一篇,继续介绍linux 套接口

    继上一篇socket层的介绍,接着说说linux的socket层的知识点,我们知道,在linux系统上,一切皆文件,之所以这么说,是因为linux系统的抽象层的设计是非常到位的,对于操作系统上的很多子 ...

  3. Linux编译内核的详细配置

    分类: Linux内核 2005-03-12 10:58 4492人阅读 评论(0) 收藏 举报 linux网络idedoswindowsdocumentation 前言之前言:谁是这篇文章的读者? ...

  4. Linux基础shell编程-琐碎知识点

    shell 脚本学习-网络野路子 shell脚本攻略 Linux命令大全(手册)_Linux常用命令行实例详解_Linux命令学习手册 Unix 基础知识 shell知识点_亦乐-可乐的博客-CSDN ...

  5. linux系统内核文百科,Linux之内核中的文件系统 -电脑资料

    文件描述符 一般说起文件和文件系统的时候,都会下意识的想到它们存在于磁盘上,管理各种文件呢?即运行时文件系统在内核中的表示. 我们知道,进程是操作系统分配资源的基本单位,文件也是在进程中被处理的.比如 ...

  6. linux新内核的freeze框架以及意义

    linux的电源管理发展非常迅速,比如在挂起到内存的时候,系统会冻结住所有的进程,也就是所有的进程都不再运行,它们被冻结之前,最后的状态被保存, 等到解冻的时候,所有进程恢复运行,linux对此的实现 ...

  7. linux c内核开发,嵌入式uClinux的内核结构和开发环境

    1 引言 嵌入式操作系统是嵌入式系统的灵魂,而且在同一个硬件平台上可以嵌入不同的嵌入式操作系统.比如ARM7TDMI内核,可以嵌入Nucleus.VxWorks.uClinux等操作系统.在此主要对u ...

  8. linux内核报告,Linux升级内核报告.docx

    Linux升级内核报告精要 我的Linux 内核升级记录 准备工作内核安装包的下载下载地址为: HYPERLINK "/pub/linux/kernel/" /pub/linux/ ...

  9. linux 内核 ntfs,Linux大脑 内核 内核编译(NTFS)

    Linux大脑 "内核" 关于它 什么是内核 kernel(内核)是操作系统的核心,相当于人的大脑,掌控所有的硬件设备的控制权,也就是希望计算机帮你完成各项工作,那都需要通过内核的 ...

最新文章

  1. 海拨3000点位的岛型堰塞湖
  2. lambda的用法与实例(转载)
  3. javaee 设计模式_JavaEE重新审视设计模式:装饰器
  4. 列表页时间日期标签靠显示html,帝国CMS列表页面list.var分别调用年月日,显示个性时间日期...
  5. 深入理解ARM体系架构(S3C6410)---lcd 显示图片
  6. A. 解决运行php文件出现乱码的问题
  7. Java八大排序详解及源码
  8. LC-130 被环绕区域
  9. java 编程规范 check list
  10. 94. autoload
  11. 智能优化算法:蜉蝣算法 - 附代码
  12. 如何清空Python的List
  13. 万字长文分析递归算法的时间和空间复杂度,从此对递归不再迷茫!
  14. html修改字体宋体,html怎么设置宋体
  15. 初秋西安,终南山Linux内核问道之旅
  16. 监控系统存储服务器和磁盘阵列,监控怎样用磁盘阵列存储服务器
  17. 这是我网店的链接欢迎来看看
  18. 用python画月亮和星空_用canvas画一轮明月,夜空与流星
  19. offer拿到手软的大佬,研究生三年是如何度过的?
  20. 【一起入门NLP】中科院自然语言处理作业四:RNN+Attention实现Seq2Seq中英文机器翻译(Pytorch)【代码+报告】

热门文章

  1. 蜜罐的详细配置过程以及所需要的的软件!以及全部配置!
  2. 7 大主题!梳理神经网络中 Normalization 的发展历程
  3. 论文速递 | 一份超全易懂的深度学习在图像去噪的综述
  4. 基于OpenCV的实用图像处理操作
  5. vue 数据绑定实现的核心 Object.defineProperty()
  6. 使用ExpandableListView以及如何优化view的显示减少内存占用
  7. windows下搭建hadoop-2.6.0本地idea开发环境
  8. 启动mysqld报 mysql the server quit without updating pid file
  9. maven编译时出现读取XXX时出错invalid LOC header (bad signature)
  10. ARM Linux (S3C6410架构/2.6.35内核)的内存映射(三)