对于进程的理解

目录

为什么会出现进程这个概念

进程切换会产生什么影响

哪些状态需要被保护呢

如何保存这些状态呢

如何调度进程

时钟中断

中断重入


为什么会出现进程这个概念

  如果没有进程这个概念,程序是如何执行的呢?那只能运行一个程序,运行完一个程序,才能接着运行下一个。哪怕上个程序中间要等待某件事十天半个月,也是没有办法的事情了。

  如果有进程这个概念呢?那么操作系统看到有个进程闲了,就不把cpu分给它了,这就是进程切换的概念。这样cpu利用率就上来了。此时还要考虑一个情况,要是一个进程一直忙,难道其他进程就只能在旁边等着吗?又规定每个进程最多能连续使用多久的cpu时间,到时间必须让给别人,这就是所谓的进程时间片。

  而由于进程的出现,可能会引发这样一个问题,某一个进程崩溃了,大家都一起玩完了。为了避免这样的情况出现,intel引入了保护模式的概念。一个进程挂了,给操作系统一个机会,清除这个进程,而不是和它一起灭亡。

  在保护模式,intel规定了不同的特权级。linux系统用0和3两个特权级。关于特权级,见保护模式下处理器特性那篇文章。咱们这个实践过程中用了三个特权级,0、1、3,比linux多用了一个1特权级,这是因为作者用的微内核,对于一些系统的功能模块给了1这个特权级,比内核低,比用户进程高。


进程切换会产生什么影响

  不同的进程执行的是不同的代码,同一个进程不同的特权级这两个问题又带来了堆栈切换的问题。因为不同的特权级、不同的进程,如果共用一个堆栈,谁也不能保证再切回去的时候堆栈没有被破坏。所以我们必须保护好切换前的执行环境。

  哪些状态需要被保护呢。

  上帝的归上帝,撒旦的归撒旦。进程的当然归进程自己了。

  又需要一个账本了:

  1. 记录每个进程还剩多少时间
  2. 记录进程此时用到的各个寄存器,比如说eip,esp这些比较重要的数据,等下次切换回来接着用
  3. 再就是联系上文件系统,还有打开的文件描述符数组
  4. 还有保护模式下LDT的选择子
  5. 还有自己的状态
  6. 进程自己的代码段和数据段描述符

  这些就完了吗?肯定不可能一次考虑周全,只能随着工作的推进,我们的考虑才能越来越完善。

  那么这些东西保存在哪里呢?如果随便保存在一个地方,系统还需要额外做个记录,既然每个进程都独有一份不同的记录,并且所需的空间是固定的,不会一会儿大一会小。这样的话,最好就是放在进程表里,既免去了系统要做的额外记录,而且进程本身如果要对这些值做修改是非常方便的(例如exec加载一个新的镜像)。


如何保存这些状态呢

  保存的地方有了,似乎就应该可以切换了。来看看有几种切换方式。

  1. 从内核态切换到用户态
  2. 从一个进程的内核态切换到另一个进程的内核态
  3. 从用户态切到内核态

  前两种状态比较好处理,都是按照保存在进程表中的寄存器顺序依次弹出即可。

  单单是从用户态到内核态有点麻烦,因为用户态的时候你不能访问内核态的数据,那么你怎么会知道你的进程表在哪里呢?那么用户态的执行环境就没法保存了。

  intel从硬件上给予了支持。在从用户态切换到内核态的时候需要用到tss段了。当因为某些信号从用户态切换到内核态时候,cpu会把ss、esp暂时保存在cpu中,然后从tr寄存器中拿到选择子,从GDT中得到tss的段基地址,然后将tss.ss0给ss寄存器,tss.esp0给esp寄存器,这两个值就相当于从用户态切换到内核态时候的堆栈指针。再把刚才保存的ss、esp加上EFLAG、cs、eip放到esp0指向的栈上。

  这就要求进程在离开内核态回到用户态的时候,必须要把tss段中的ss0和esp0的值设置为自己进程表中保存用户执行环境的起始地址。

  保护进程的现场,好像又引出了不少东西。GDT、LDT、TSS。其实它们几个都是内存中的一张表。网上都有说明。

  说一下以前自己容易忽略的LDT寻址的细节。

  当TI=1时表示段描述符在LDT中:

  1. 还是先从GDTR寄存器中获得GDT基址。
  2. 从LDTR寄存器中获取LDT所在段的位置索引(LDTR高13位)。而LDTR的内容是用lldt加载的,这个时候就清楚了代码中从内核返回的时候为什么要加载进程各自的LDT选择子了。
  3. 以这个位置索引在GDT中得到LDT段描述符从而得到LDT段基址。LDT表是作为一个段存在的。从这可以看出来GDT是总目录,大家都要从要作为起点来寻址。
  4. 用段选择器高13位位置索引值从LDT段中得到段描述符。(此时是段选择子,一般是cs)
  5. 段描述符符包含段的基址、限长、优先级等各种属性,这就得到了段的起始地址(基址),再以基址加上偏移地址yyyyyyyy才得到最后的线性地址。(cpu来完成)

  似乎进程这个值得费笔墨的知识点真的没有什么东西可以说的了。

  也难怪,伟大的东西似乎都是简单的。


如何调度进程

  那进程切换的时机呢?总不能让进程自己决定什么时候不用cpu了吧?万一有个无赖怎么办?

时钟中断

  这个时候,中断就是一个非常好的仲裁者了,依靠物理特性,准时准点的报时。系统只需要在石英晶体报时的时候做一些计算就可以了。

  在时钟中断里面,我们可以来判断当前进程是不是把时间片用完了,那系统从准备好的进程队列中挑选一个进程来执行。当然,这个挑选的过程可以简单也可以复杂,看实现者想做什么了。目前我们要做的比较简单,每个进程分配一些时间片,每次时钟中断里面把当前进程的时间片减1,等于0的时候,被系统拿掉cpu的使用权,让下一个进程使用cpu。

中断重入

  时钟中断还是比较简单的,设置好8259A就可以响应中断信号了。但是在书中,作者又让我了解到中断重入的概念。以前看linux 0.12的时候时钟中断的代码中却是没有重入的概念。

  来看一下cpu响应中断时候会发生什么:

  CPU响应中断后,输出中断响应信号,自动将状态标志寄存器的内容压入堆栈保护起来,然后将状态标志寄存器中的中断标志位IF与陷阱标志位TF清零,从而自动关闭外部硬件中断。因为CPU刚进入中断时要保护现场,主要涉及堆栈操作,此时不能再响应中断,否则将造成系统混乱。

  书中给出的实例是保存了寄存器现场后用sti指令打开了中断,所以允许中断重入,而linux 0.12中进入中断后没有做额外的处理,所以不用理会中断的重入。

  处理中断重入也不算难,需要定义一个全局变量,并初始化为-1。进入中断对这个变量加1,如果本次的计算结果不等于0,说明是重入的中断,直接结束本次中断。

时间: 2024-08-26 05:08:50

对于进程的理解的相关文章

线程与进程的理解

1.进程和线程的区别:http://www.cnblogs.com/lmule/archive/2010/08/18/1802774.html 2.新手学习多线程的详细思路和流程:http://www.cnblogs.com/xiaoguangit/p/4991825.html 3.我是一个线程:http://kb.cnblogs.com/page/542462/ 4.多线程编程基础知识:http://www.cnblogs.com/cy163/archive/2006/11/02/547428

根据现实中一个实例--线程和进程的理解

进程(process)和线程(thread) 是所有学习计算机行业人员绕不过去的两个基本概念,但是它们却十分的抽象,十分不容易理解. 最近总结了一个例子来解释一下,可能要好一点. 1.我们知道,CUP是一个计算机的核心,它就像一个工厂一样,只要启动计算机,它就会一刻不停的运动.我这样假设,这个工厂的名字是xxx工厂,这个工厂里面有5个车间,车间门牌号是,"1","2","3","4","5",每个车间的标准

对Linux进程的理解

在本科期间学习过进程,网上也有很多关于进程的知识,但对于进程到底是什么一直没有让我满意的解答(以下截图来自网络,感觉对进程理解有问题,说得也很虚). 但今天找到这个博文感觉挺符合我的胃口:http://blog.csdn.net/yuqiang_ee_android/article/details/16889257 进程的本质 进程是Linux内核提供的一个环境(资源分配的基本单位),包括: (1)进程控制块(用于操作系统对进程的管理). (2)虚拟内存(分为好几段:正文段.数据段.BBS段.堆

关于线程和进程的理解

在知乎上看的关于线程和进程的形象理解,留作纪念. 这个场景是这样子的,山上有座庙(进程),庙里住了很多小和尚和老和尚(线程),当然隔壁山上也有很多尼姑妹子.小和尚和老和尚们每天都需要下山挑水喝.这些个和尚有刚上山的(就是有点傻的),有比较聪明的,也有闹过矛盾的.场景,人物呢,大概就是这么个样子. 俗话说的好,有人的地方就有江湖.这些个小和尚,老和尚都不是很安分,为了每天的这个挑水工作闹了很多很多的矛盾,也犯过很多傻. 下面对挑水工作所有发生的情况做个详述: 1)刚上山的小和尚挑水,就是比较傻的那

Linux 进程的理解

进程的描述 通俗的讲,进程就是正在执行的程序或代码.我们知道,程序本身就是一堆代码,开始的时候存储在磁盘上,这时它是静态的.无生命的:只有当程序的代码被加载到内存中,代码才有了生命,才能被CPU动态的执行. 问题是,现在的操作系统可以并行的执行多个程序,也就是内存中同时存放着多个程序的代码,为了方便管理,必须要合理的组织它们.方式就是由操作系统给每段代码添加一些元数据,这些元数据就是PCB,即任务控制块. 不难理解的是,每个程序的代码实际上可以分为两部分:指令的数据.指令就是程序代码规定的各种操

线程和进程的理解

今天看了一下进程和线程的一些概念,对线程和进程进行了理解,现在用我实际生活中的一段经历来理解线程和进程. 2008年第一次去老公家, 从北京到山东,整个乘车行程可以说成是一个进程. 记得很清楚,在沧州的时候换了一次车,那么A段(从北京到沧州)可以看成是一个线程,B段(从沧州到山东目的)是一个线程 所以一个进程可以有多个线程,此时的线程是有先后顺序的,A段执行完成了再执行B段.

谈谈对线程与进程的理解

概念: 线程 线程(threading)是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. 进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体:在当代面向线程设计的计算机结构中,进程是线程的容器.程序是指令.数据及其组织形式的描

通过开始执行shell进程,理解缺页异常

通过进程2加载shell进程,详解execve,这篇文章,最后shell程序开始执行的线性地址是128MB,由于free_page_tables,已经释放了第32位页目录项.所以会产生缺页异常.程序会执行,如下代码: do_no_page void do_no_page(unsigned long error_code,unsigned long address)//address为128MB { int nr[4]; unsigned long tmp; unsigned long page;

线程、进程 概念理解

1 .什么是线程? 线程是指程序在执行过程中,能够执行程序代码的一个执行单元,在 Java 语言中,线程有四种状态:运行,就绪,挂起,结束. 2 .线程与进程的区别? 进程是一段正在运行的程序,而线程有时也被称为轻量级进程,它是进程的执行单元,一个进程可以拥有多个线程,各个线程之间共享程序的内存空间,但是,各个线程拥有自己的栈空间. 3 .为什么使用多线程? ( 1 ).使用多线程可以减少程序的响应时间.单线程如果遇到等待或阻塞,将会导致程序不响应鼠标键盘等操作,使用多线程可以解决此问题,增强程