国防科大OS10-1章节

上传人:E**** 文档编号:91443198 上传时间:2019-06-28 格式:PPT 页数:36 大小:186KB
返回 下载 相关 举报
国防科大OS10-1章节_第1页
第1页 / 共36页
国防科大OS10-1章节_第2页
第2页 / 共36页
国防科大OS10-1章节_第3页
第3页 / 共36页
国防科大OS10-1章节_第4页
第4页 / 共36页
国防科大OS10-1章节_第5页
第5页 / 共36页
点击查看更多>>
资源描述

《国防科大OS10-1章节》由会员分享,可在线阅读,更多相关《国防科大OS10-1章节(36页珍藏版)》请在金锄头文库上搜索。

1、教材及参考文献 Understanding the Linux Kernel second editionDaniel P. Bovet&Marco Cesati,OREILLY,2002 深入理解Linux内核第二版,陈莉君等译,中国电力出版社,2004 Linux内核代码情景分析上下册,胡希明 毛德操,浙江大学出版社,2001 边学边干Linux内核指导李善平等,浙江大学出版社,2002 源码阅读网站http:/lxr.Linux.no/source 源码网站:http:/www.kernel.org/pub/linux/kernel,命令解释器,数据库管理器,数据库应用,编辑器,Linu

2、x内核,硬件层,C库/数学库/图形库/窗口库等,系统调用库,X服务器,窗口管理器,窗口应用,系统概貌,Linux内核在核心态下运行,内核程序包含/boot/vmlinux及/lib/modules/下的各种可加载模块。,内核概貌 内核程序嵌在一个用户进程的上下文中运行(因系统调用,中断入核)也有部分程序是以几个独立的纯内核线程运行的。 进程运行在用户态时各进程空间分离(如果要共享需要shmget等系统调用支持),各进程运行核心程序时共享内核空间。,实验 增加系统调用实现内核参数读写。 利用建立proc文件系统的文件实现内核参数读写。 利用动态加载内核模块将特定功能函数插入open及close系

3、统调用处理过程,以记录用户对资源的使用信息。 设计事件同步系统调用,当一个事件发生时,等事件的所有进程被就绪。 建立一个简单只有一级目录的内存文件系统。 设计一个内存设备驱动程序。 设计USB驱动程序,第十章 Linux操作系统 本章内容:进程管理;存储管理;文件系统;设备管理;中断、异常及系统调用;进程通讯。 10.1 进程管理,内容 进程描述符 进程的调度时机及调度算法 进程的创建与消亡,10.1.1 进程与进程描述符 1 进程概念 LINUX进程与传统UNIX进程的概念没有多大区别 LINUX通过clone()系统调用支持轻权进程(相当于内核级线程) LINUX还支持内核线程的概念,内核

4、线程永远在核心态运行,没有用户空间 2 进程描述符(进程控制块) 由一个task_struct结构表示。task_struct结构是一个复杂的结构,占一千多字节,其各个成员用来准确描述进程在各方面的信息.主要有以下几个部分:,(1) 进程标识 包括进程的标识号(pid)、进程的用户标识、进程的组标识等。每个进程的标识号是唯一的。 (2) 调度相关信息 这部分内容与进程调度有关,一部分信息见后面的第5节。进程描述符中还需要有结构保存当进程被剥夺处理机时寄存器的状态,该进程恢复运行时便可从正确的状态继续运行。 (3) 进程虚拟空间信息 LINUX的进程都在自己的私有地址空间中运行,task_str

5、uct的成员mm指向一个mm_struct结构,该结构描述进程空间。,(4) 信号处理信息 LINUX支持传统的UNIX信号语义。该部分记录了信号的处理函数及信号掩码等信息。 (5)文件相关信息 包含进程与文件系统交互的信息。主要分为两部分,一部分描述进程进行文件访问时用到的当前目录、根目录信息。另一部分描述被进程正在使用的文件信息,该部分主要有一个file结构数组,数组中的有效项指向某个文件对象。 (6)记帐信息及统计信息 资源是有限的,每个进程对每种资源的使用都有一个限值。另外,还有统计信息来记录系统需要的信息,如页面异常次数、CPU使用时间等。,(7) 描述进程间关系的指针 所有的进程通

6、过一个双向链表链接在一起。通过宏for_each_task可以对每个进程操作。 指向其父进程、子进程、兄弟进程描述符的指针 需要根据pid号能够快速找到进程,系统以pid为关键字建立了一个哈希表, 哈希函数值相同的进程通过进程描述符的pidhash_next和pidhash_pprev成员链在一起。,10.1.2 核心态与核心栈 LINUX的运行分为两种模式核心态和用户态。内核总在核心态下运行,而普通进程通常在用户模式下运行,只有通过系统调用/中断才能切换到核心态运行。 进程拥有两个栈,用户模式栈与核心模式栈,分别在相应模式下使用。进程描述符和进程核心栈的空间分配在一起,内核为它们分配两个连续

7、的物理页面。,union task_union struct task_struct task; unsigned long stack2048; ;,因为进程描述符已经占用了1KB多的空间,所以核心栈的有效空间是6KB多一点,合理的设计使得这个容量已经足够了,两个物理页帧 8KB,进程描述符,核心模式栈,图101 核心栈与进程描述符,10.1.3 进程状态及状态转换图 LINUX的进程状态有五种,它们分别是: TASK_RUNNING:表示进程具备运行的资格,要么正在运行,要么就是等待被调度执行。进程描述符有一个run_list成员,所有处于TASK_RUNNING状态的进程都通过该成员链在

8、一起,称之为可运行队列。 TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE:这两种状态均表示进程处于睡眠状态。TASK_INTERRUPTIBLE除了资源满足时可以被唤醒外,还可以被信号唤醒,而TASK_UNINTERRUPTIBLE就不行。,TASK_STOPPED:进程处于暂停状态,主要用于调试目的。如正在运行的进程收到SIGSTOP信号将进入TASK_STOPPED状态。 TASK_ZOMBIE:表示进程已经结束运行并释放了大部分占用的资源,但task_struct结构还未被释放。,10.1.4 进程的切换时机 1 当前进程放弃CPU的情况可以分为两种: 1

9、.1 进程主动地放弃CPU 大体可以分为两类 隐式地主动放弃CPU。往往是因为需要的资源目前不能获取,如执行read()、select()等系统调用的过程中。这种情况下的处理过程如下: (1)将进程加入合适的等待队列。 (2)把当前进程的状态改为TASK_INTERRUTIBLE或TASK_UNINTERRUTIBLE。 (3)调用schedule()函数,该函数的执行结果往往是当前进程放弃CPU。,(4) 检查资源是否可用,如果不可用,则跳转到第(2)步 (5)资源已可用,将该进程从等待队列中移去。,进程显式地主动放弃CPU,如系统调用sched_yield()、sched_setsched

10、uler()、pause()、及nanosleep()均会导致当前进程让出CPU。,1.2 进程被动放弃CPU 两种情形均会导致当前进程描述符的need_resched被置1 当前进程的时间片已经用完 刚被唤醒进程的优先级别高于当前进程。,2 进程的调度时机 分成两种情形。 直接调用schedule()调度函数 例如进程主动放弃CPU的第一类情形 间接调用schedule() 例如进程被动放弃CPU的情形。当进程描述符的need_resched被置1时,并不立即直接调用schedule()调度函数。而是在随后的某个时刻,当进程从内核态返回用户态之前检查need_resched是否为1,如果为1

11、,则调用schedule()调度函数。,10.1.5 进程的调度算法 核心函数是schedule(),该函数的任务是选出一个可运行的进程。 1 进程描述符有如下成员域与调度有关: (1)policy 标识进程的调度策略 SCHED_OTHER 普通进程 SCHED_FIFO 实时进程,采用先进先 出的调度算法 SCHED_RR 实时进程,采用轮转法,(2) rt_priority 实时进程的优先级,普通进程不使用这个成员 (3) nice 普通进程的优先级 (4) counter 进程目前的CPU时间配额,2 对于普通进程来讲CPU时间的分配是典型的时分策略 在某个时刻,运行队列中的每个进程都

12、有一个counter值,当所有运行队列中的counter值都变为0以后,表明一轮已经结束,每个进程的counter根据其nice重新赋值,开始新的一轮执行过程。拥有CPU的进程每次时钟中断counter值减一。,3 schedule()函数执行过程: (1)检查当前进程是否有软中断信号服务请求,如果有,则先处理这些请求 (2)若当前进程调度策略是SCHED_RR 且 counter为0,则将该进程移到可执行进程队列的尾部 (3)检查当前进程的状态,如为 TASK_INTERRUPTIBLE 且该进程有信号则将进程状态置为 TASK_RUNNING (4)当前进程的状态不是TASK_RUNNIN

13、G则将其从可执行进程队列中移出。然后将当前进程描述符的need_resched恢复成0。,(5)现在进入了函数的核心部分。可运行进程队列的每个进程都将被计算出一个权值,主要是利用goodness()函数,讨论见后。最终最大的权值保存在变量c中,与之对应的进程描述符保存在变量next中。 (6)检查c是否为0。若为0则表明所有可执行进程的时间配额都已用完,则对所有进程的counter重新“充电”,然后重新执行第(5)步。 (7)如果next进程就是当前进程,则结束shedule()的运行。否则进行进程切换,CPU改由next进程占据。,4 goodness()函数 goodness()函数计算进

14、程的当前权值。该函数的第一个参数是待估进程的描述符。 如果该进程是实时进程,它的权值为 1000rt_priority,1000是普通进程权值无法到达的数字,因而实时进程总可以优先得到执行。 对于普通进程,它的权值为counter20-nice,如果其又是内核线程,由于无需切换用户空间,则将权值加一作为奖励。,10.1.6 进程的创建 1 进程的起源 LINUX最早产生的进程是启动过程中创建出idle进程(不是通过fork(),而是直接填表制作出来),pid号为0,该进程通过调用内核函数将创建一个内核线程,该线程进行一系列初始化动作后最终会执行/sbin/init文件,执行该文件的结果是运行模

15、式从核心态切换到了用户态,该线程演变成了用户进程init,pid号为1。init进程是一个非常重要的进程,一切用户态进程都是它的后代进程。,进程的产生及结构,0进程(idle) 初启创建,系统初始化后作为idle进程 1进程( init ) 由 0进程创建,创建各系统进程,创建getty子 进程监视终端执行login,注册登记. 终端进程 . . 终端进程 执行 shell解释程序 命令处理子进程 . 子进程 外部命令 子进程 . . 子进程,2 fork/exec 新进程的产生模式 通常fork()创建一个新进程,然后新进程通过调用exec系列函数执行真正的执行文件。 函数fork()调用成

16、功的话,当前进程就拥有了一个子进程。该函数对不同的进程返回两个不同的值,其中子进程返回0,父进程返回的是子进程的pid值。下面是一段示例代码:,int main(void) pid_t pid; if(pid = fork() 0) printf(“fork failedn“); exit(1); else if(pid = 0) /*子进程执行进入此部分*/ execlp(“echoall“,“echoall“,(char*)0); else /*父进程*/ printf(“fork successn“); exit(0); ,3 sys_clone() sys_vfork() sys_fork() 三个系统调用都可以实现创建子进程,这三个系统调用最终都会调用do_fork()函数完成主要工作。 该函数的第一个参数clone_flags可由多个标志位组成,常见的标志位有: CLONE_VM 子进程父进程共享进程空间 CLONE_F

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号