嵌入式操作系统进程.ppt

上传人:wj 文档编号:14999225 上传时间:2023-06-29 格式:PPT 页数:80 大小:582KB
下载 相关 举报
嵌入式操作系统进程.ppt_第1页
第1页 / 共80页
嵌入式操作系统进程.ppt_第2页
第2页 / 共80页
嵌入式操作系统进程.ppt_第3页
第3页 / 共80页
嵌入式操作系统进程.ppt_第4页
第4页 / 共80页
嵌入式操作系统进程.ppt_第5页
第5页 / 共80页
嵌入式操作系统进程.ppt_第6页
第6页 / 共80页
嵌入式操作系统进程.ppt_第7页
第7页 / 共80页
嵌入式操作系统进程.ppt_第8页
第8页 / 共80页
嵌入式操作系统进程.ppt_第9页
第9页 / 共80页
嵌入式操作系统进程.ppt_第10页
第10页 / 共80页
嵌入式操作系统进程.ppt_第11页
第11页 / 共80页
嵌入式操作系统进程.ppt_第12页
第12页 / 共80页
嵌入式操作系统进程.ppt_第13页
第13页 / 共80页
嵌入式操作系统进程.ppt_第14页
第14页 / 共80页
嵌入式操作系统进程.ppt_第15页
第15页 / 共80页
嵌入式操作系统进程.ppt_第16页
第16页 / 共80页
嵌入式操作系统进程.ppt_第17页
第17页 / 共80页
嵌入式操作系统进程.ppt_第18页
第18页 / 共80页
嵌入式操作系统进程.ppt_第19页
第19页 / 共80页
嵌入式操作系统进程.ppt_第20页
第20页 / 共80页
亲,该文档总共80页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

嵌入式操作系统进程.ppt

《嵌入式操作系统进程.ppt》由会员分享,可在线阅读,更多相关《嵌入式操作系统进程.ppt(80页珍藏版)》请在冰点文库上搜索。

嵌入式操作系统进程.ppt

嵌入式操作系统,xlanchen2007.6.12Spring2007Suzhou,Jiangsu,China,xlanchen2007.6.12,EmbeddedOperatingSystems,2,昨天课程内容回顾,Linux内核分析的一些基础知识堆栈用户态/内核态虚拟内存内存寻址,xlanchen2007.6.12,EmbeddedOperatingSystems,3,今天课程内容概述,Linux中的进程管理进程描述符进程切换进程的创建和删除进程调度,进程,xlanchen2007.6.12Spring2007Suzhou,Jiangsu,China,xlanchen2007.6.12,EmbeddedOperatingSystems,5,主要内容,进程描述符进程切换进程的创建和删除进程调度,xlanchen2007.6.12,EmbeddedOperatingSystems,6,进程的概念,进程是执行程序的一个实例进程和程序的区别几个进程可以并发的执行一个程序一个进程可以顺序的执行几个程序,xlanchen2007.6.12,EmbeddedOperatingSystems,7,进程描述符,为了管理进程,内核必须对每个进程进行清晰的描述。

进程描述符提供了内核所需了解的进程信息include/linux/sched.hstructtask_struct数据结构很庞大,xlanchen2007.6.12,EmbeddedOperatingSystems,8,xlanchen2007.6.12,EmbeddedOperatingSystems,9,Linux进程的状态,可运行状态(TASK_RUNNING)可中断的等待状态(TASK_INTERRUPTIBLE)不可中断的等待状态(TASK_UNINTERRUPTIBLE)暂停状态(TASK_STOPPED)僵死状态(TASK_ZOMBIE),xlanchen2007.6.12,EmbeddedOperatingSystems,10,进程状态转换图,xlanchen2007.6.12,EmbeddedOperatingSystems,11,标识一个进程,使用进程描述符地址进程和进程描述符之间有非常严格的一一对应关系,使得用32位进程描述符地址标识进程非常方便使用PID(ProcessID,PID)每个进程的PID都存放在进程描述符的pid域中,xlanchen2007.6.12,EmbeddedOperatingSystems,12,进程描述符和进程的内核堆栈,Linux为每个进程分配一个8KB大小的内存区域,用于存放该进程两个不同的数据结构:

进程描述符进程的内核堆栈进程处于内核态时使用不同于用户态堆栈内核控制路径所用的堆栈很少,因此对栈和描述符来说,8KB足够了,xlanchen2007.6.12,EmbeddedOperatingSystems,13,Task_union,C语言允许用如下的一个union结构来方便的表示这样的一个混合体进程描述符的分配/回收/访问,=2048,xlanchen2007.6.12,EmbeddedOperatingSystems,14,current宏进程描述符,从刚才看到的进程描述符和内核态堆栈之间的配对,内核可以很容易的从esp寄存器的值获得当前在CPU上运行的进程的描述符指针因为这个内存区是8KB=213大小,内核必须做的就是让esp有13位的有效位,以获得进程描述符的基地址这个工作由current宏来完成,8191=8192-1=0x2000-1=0x1fff取反:

0xffffe000(最后13位为0),xlanchen2007.6.12,EmbeddedOperatingSystems,15,Current宏的使用,Current宏可以看成当前进程的进程描述符指针,在内核中直接使用比如current-pid返回在CPU上正在执行的进程的PID,xlanchen2007.6.12,EmbeddedOperatingSystems,16,进程链表,为了对给定类型的进程(比如所有在可运行状态下的进程)进行有效的搜索,内核维护了几个进程链表所有进程链表,在进程描述符中:

xlanchen2007.6.12,EmbeddedOperatingSystems,17,SET_LINKS和REMOVE_LINKS宏用来分别在进程链表中插入和删除一个进程描述符。

xlanchen2007.6.12,EmbeddedOperatingSystems,18,for_each_task宏扫描整个进程链表,xlanchen2007.6.12,EmbeddedOperatingSystems,19,TASK_RUNNING状态的进程链表,当内核调度程序寻址一个新的进程在cpu上运行时,必须只考虑可运行进程,因为扫描整个进程链表效率很低引入了可运行状态的双向循环链表,也叫运行队列进程描述符使用用来实现运行队列,xlanchen2007.6.12,EmbeddedOperatingSystems,20,对可运行队列的一些操作函数,增加/删除一个可运行进程,可运行队列的长度,可运行进程的个数,唤醒一个进程,使一个进程可运行,xlanchen2007.6.12,EmbeddedOperatingSystems,21,pidhash表及链接表,在一些情况下,内核必须能从进程的PID得出对应的进程描述符指针。

例如kill系统调用为了加速查找,引入了pidhash散列表用pid_hashfn宏把PID转换成表的索引,xlanchen2007.6.12,EmbeddedOperatingSystems,22,pidhash表及链接表,xlanchen2007.6.12,EmbeddedOperatingSystems,23,进程之间的亲属关系,程序创建的进程具有父子关系,在编程时往往需要引用这样的父子关系。

进程描述符中有几个域用来表示这样的关系,xlanchen2007.6.12,EmbeddedOperatingSystems,24,等待队列,当要把除了TASK_RUNNING状态之外的进程组织在一起时,linux使用了等待队列TASK_STOPPED和TASK_ZOMBIE不在专门的链表中TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE状态的进程再分成很多类,每一类对应一个特定的事件。

在这种情况下,进程状态提供的信息满足不了快速检索,因此,内核引进了另外的进程链表,叫做等待队列等待队列在内核中有很多用途,尤其是对中断处理、进程同步和定时用处很大,xlanchen2007.6.12,EmbeddedOperatingSystems,25,等待队列使得进程可以在事件上的条件等待,并且当等待的条件为真时,由内核唤醒它们等待队列由循环链表实现在等待队列上内核实现了一些操作函数Add_wait_queueremove_wait_queue,xlanchen2007.6.12,EmbeddedOperatingSystems,26,等待队列的链表,xlanchen2007.6.12,EmbeddedOperatingSystems,27,进程等待,等待一个特定事件的进程能调用下面几个函数中的任一个sleep_onsleep_on_timeoutinterruptible_sleep_oninterruptible_sleep_on_timeout进程等待由需要等待的进程自己进行(调用),xlanchen2007.6.12,EmbeddedOperatingSystems,28,sleep_on,xlanchen2007.6.12,EmbeddedOperatingSystems,29,进程的唤醒,利用wake_up或者wake_up_interruptible等一系列的宏,都让插入等待队列中的进程进入TASK_RUNNING状态,xlanchen2007.6.12,EmbeddedOperatingSystems,30,进程切换(processswitching),为了控制进程的执行,内核必须有能力挂起正在CPU上执行的进程,并恢复以前挂起的某个进程的执行,这叫做进程切换,任务切换,上下文切换,xlanchen2007.6.12,EmbeddedOperatingSystems,31,进程上下文,包含了进程执行需要的所有信息用户地址空间包括程序代码,数据,用户堆栈等控制信息进程描述符,内核堆栈等硬件上下文,xlanchen2007.6.12,EmbeddedOperatingSystems,32,硬件上下文,尽管每个进程可以有自己的地址空间,但所有的进程只能共享CPU的寄存器。

因此,在恢复一个进程执行之前,内核必须确保每个寄存器装入了挂起进程时的值。

这样才能正确的恢复一个进程的执行硬件上下文:

进程恢复执行前必须装入寄存器的一组数据包括通用寄存器的值以及一些系统寄存器通用寄存器如eax,ebx等系统寄存器如eip,esp,cr3等等,xlanchen2007.6.12,EmbeddedOperatingSystems,33,在linux中一个进程的硬件上下文主要保存在thread_struct中其他信息放在内核态堆栈中,xlanchen2007.6.12,EmbeddedOperatingSystems,34,thread_struct,xlanchen2007.6.12,EmbeddedOperatingSystems,35,上下文切换,switch_to宏执行进程切换,schedule()函数调用这个宏一调度一个新的进程在CPU上运行演示:

在schedule()中找到调用switch_to宏的位置switch_to利用了prev和next两个参数:

prev:

指向当前进程next:

指向被调度的进程,xlanchen2007.6.12,EmbeddedOperatingSystems,36,当前进程仍然是prev这个push操作针对的是当前进程的堆栈,保存esi,edi,ebp,保存esp到%0中,嵌入式汇编中用这种方法表示输入、输出参数,可以从0开始编号,%0是什么?

保存esp到当前进程的上下文中,从next的上下文中取出堆栈的位置,将其作为当前堆栈,堆栈被切换,在prev进程的上下文中设置返回地址,返回到下面标号为1处,从next进程的上下文中取得该进程的返回地址,放入堆栈中,调用_switch_to函数,xlanchen2007.6.12,EmbeddedOperatingSystems,37,进程切换的关键语句,堆栈的切换从此,内核对next的内核态堆栈操作,因此,这条指令执行从prev到next真正的上下文切换,因为进程描述符和内核态堆栈紧密联系在一起,改变内核态堆栈就意味改变当前进程,xlanchen2007.6.12,EmbeddedOperatingSystems,38,什么时候next进程真正开始执行呢?

call=保存返回地址+跳转到target处执行ret=从堆栈上获得返回地址,并跳转到该返回地址处执行?

当_switch_to正常返回时,发生了什么事情?

xlanchen2007.6.12,EmbeddedOperatingSystems,39,标号为1的执行代码处,一个进程被正常切换出时,保存的eip总是标号为1的那个位置当这个进程再次被调度运行时,恢复在堆栈上的返回地址总是这个11:

popl%ebppopl%edipopl%esi,xlanchen2007.6.12,EmbeddedOperatingSystems,40,_switch_to,_switch_to用来处理其他上下文的切换此时,使用的堆栈是next进程的堆栈,这个堆栈上没有_switch_to需要的参数prev和next怎么传参呢?

演示:

找到_switch_to的函数定义和函数声明找到FASTCALL的定义,xlanchen2007.6.12,EmbeddedOperatingSystems,41,_switch_to的关键操作,unlazy_fpu()处理数学协处理器保存和恢复fs、gs等等,xlanchen2007.6.12,EmbeddedOperatingSystems,42,?

哪里切换了进程的地址空间,xlanchen2007.6.12,EmbeddedOperatingSystems,43,进程的创建,许多进程可以并发的运行同一程序,这些进程共享内存中程序正文的单一副本,但每个进程有自己的单独的数据和堆栈区一个进程可以在任何时刻可以执行新的程序,并且在它的生命周期中可以运行几个程序又如,只要用户输入一条命令,shell进程就创建一个新进程,xlanchen2007.6.12,EmbeddedOperatingSystems,44,Linux提供了几个系统调用来创建和终止进程,以及执行新程序Fork,vfork和clone系统调用创建新进程exec系统调用执行一个新程序exit系统调用终止进程(进程也可以因收到信号而终止),xlanchen2007.6.12,EmbeddedOperatingSystems,45,fork,fork系统调用创建一个新进程调用fork的进程称为父进程新进程是子进程子进程几乎就是父进程的完全复制。

它的地址空间是父进程的复制,一开始也是运行同一程序。

fork系统调用为父子进程返回不同的值,xlanchen2007.6.12,EmbeddedOperatingSystems,46,exec,很多情况下,子进程从fork返回后很多会调用exec来开始执行新的程序这种情况下,子进程根本不需要读或者修改父进程拥有的所有资源。

所以fork中地址空间的复制依赖于CopyOnWrite技术,降低fork的开销,xlanchen2007.6.12,EmbeddedOperatingSystems,47,写时复制技术,写时复制技术允许父子进程能读相同的物理页。

只要两者有一个进程试图写一个物理页,内核就把这个页的内容拷贝到一个新的物理页,并把这个新的物理页分配给正在写的进程,xlanchen2007.6.12,EmbeddedOperatingSystems,48,使用fork和exec的例子,If(result=fork()=0)/*子进程代码*/if(execve(“new_program”,)0)perror(“execvefailed”);exit

(1);elseif(result0)perror(“forkfailed”)/*result=子进程的pid,父进程将会从这里继续执行*/,xlanchen2007.6.12,EmbeddedOperatingSystems,49,分开这两个系统调用是有好处的比如服务器可以fork许多进程执行同一个程序有时程序只是简单的exec,执行一个新程序在fork和exec之间,子进程可以有选择的执行一系列操作以确保程序以所希望的状态运行重定向输入输出关闭不需要的打开文件改变UID或是进程组重置信号处理程序若单一的系统调用试图完成所有这些功能将是笨重而低效的现有的fork-exec框架灵活性更强清晰,模块化强,xlanchen2007.6.12,EmbeddedOperatingSystems,50,do_fork,不论是fork,vfork还是clone,在内核中最终都调用了do_fork,xlanchen2007.6.12,EmbeddedOperatingSystems,51,xlanchen2007.6.12,EmbeddedOperatingSystems,52,阅读do_fork,了解大致程序流程?

子进程从哪里开始执行,它的返回值是什么?

xlanchen2007.6.12,EmbeddedOperatingSystems,53,注意:

childregs指针指向哪里,eax寄存器用作返回值,这里强制为0,在上下文中,设置用户态堆栈指针,设置内核态堆栈指针,被调度后,执行入口强制从ret_from_fork返回用户态,此后,由于子进程处于调度队列上,因此在合适的时候会被调度,调度时根据这里设置的上下文返回用户态,xlanchen2007.6.12,EmbeddedOperatingSystems,54,子进程的内核态堆栈,进程描述符,子进程的8Kunion,esp,返回值eax被强制写0,用户态堆栈esp的值,用户态下eip的值,子进程恢复到用户态时需要的上下文,eip,esp,子进程的硬件上下文,ret_from_fork,低地址,高地址,xlanchen2007.6.12,EmbeddedOperatingSystems,55,子进程的执行,fork后,子进程处于可运行状态,由调度器决定何时把CPU交给这个子进程进程切换后因为eip指向ret_from_fork,所以CPU立刻跳转到ret_from_fork()去执行。

接着这个函数调用ret_from_sys_call(),此函数用存放在栈中的值装载所有寄存器,并强迫CPU返回用户态,xlanchen2007.6.12,EmbeddedOperatingSystems,56,内核线程,系统把一些重要的任务委托给周期性执行的进程刷新磁盘高速缓存交换出不用的页框维护网络链接等待内核线程与普通进程的差别每个内核线程执行一个单独指定的内核函数只运行在内核态只使用大于PAGE_OFFSET的线性地址空间,xlanchen2007.6.12,EmbeddedOperatingSystems,57,线程和进程的比较,Linux内核中没有线程的概念没有针对所谓线程的调度策略没有数据结构用来表示一个线程一般线程的概念在linux中只是表现为一组共享资源的进程(每个这样的进程都有自己的进程描述符)在其他系统中(比如windows)线程是实实在在的一种运行抽象,提供了比进程更轻更快的调度单元在linux中“线程”仅仅是表示多个进程共享资源的一种说法,xlanchen2007.6.12,EmbeddedOperatingSystems,58,创建内核线程,Kerenl_thread()创建一个内核线程,并且只能由另一个内核线程来执行这个调用,xlanchen2007.6.12,EmbeddedOperatingSystems,59,进程树,进程0进程1,xlanchen2007.6.12,EmbeddedOperatingSystems,60,进程0,所有进程的祖先叫做进程0在系统初始化阶段由start_kernel()函数从无到有手工创建的一个内核线程存放在init_task_union变量中的一个进程描述符和一个内核态堆栈(回忆一下启动时,堆栈的初始化)用INIT_MM,INIT_MMAP,INIT_FS,INIT_FILES,INIT_SIGNALS宏初始化进程描述符的各个对应域页全局目录,swapper_pg_dir变量进程0最后的初始化工作创建init内核线程,此后运行cpu_idle,成为idle进程,xlanchen2007.6.12,EmbeddedOperatingSystems,61,进程1,又称为init进程由进程0在start_kernel调用rest_init创建init进程PID为1,当调度程序选择到init进程时,init进程开始执行init()函数,xlanchen2007.6.12,EmbeddedOperatingSystems,62,init()为常规内核任务初始化一些必要的内核线程,如:

kflushd刷新脏缓冲区中的内容到磁盘以归还内存kswapd执行内存回收功能的线程最后init()函数调用execve()系统调用装入可执行程序init。

从此,init内核线程变成一个普通的进程。

但init进程从不终止,因为它创建和监控操作系统外层的所有进程的活动,xlanchen2007.6.12,EmbeddedOperatingSystems,63,撤销进程,进程终止进程终止的一般方式是exit()系统调用。

这个系统调用可能由编程者明确的在代码中插入另外,在控制流到达主过程C中的main()函数的最后一条语句时,执行exit()系统调用内核可以强迫进程终止当进程接收到一个不能处理或忽视的信号时当在内核态产生一个不可恢复的CPU异常而内核此时正代表该进程在运行,xlanchen2007.6.12,EmbeddedOperatingSystems,64,撤销进程,进程终止使用exit系统调用删除进程在父进程调用wait()类系统调用检查子进程是否合法终止以后,就可以删除这个进程,xlanchen2007.6.12,EmbeddedOperatingSystems,65,演示进程的创建ps可以显示系统中的进程试一下:

psaux,xlanchen2007.6.12,EmbeddedOperatingSystems,66,进程调度,调度策略调度算法,xlanchen2007.6.12,EmbeddedOperatingSystems,67,调度策略(schedulingpolicy),决定什么时候以怎样的方式选择一个新进程运行的一组规则Linux的调度基于分时技术允许多个进程“并发”运行CPU的时间被划分成“片”,给每个可运行进程分配一片在单处理器上,任何时刻只能运行一个进程,当一个并发执行的进程时间片用完时(到期)还没有终止,就可以进行进程切换分时依赖于时钟中断,对进程透明,xlanchen2007.6.12,EmbeddedOperatingSystems,68,Linux的进程根据优先级排队根据特定的算法计算出进程的优先级,用一个值表示这个值表示把进程如何适当的分配给CPULinux中进程的优先级是动态的调度程序会根据进程的行为周期性的调整进程的优先级较长时间未分配到CPU的进程,通常已经在CPU上运行了较长时间的进程,通常,xlanchen2007.6.12,EmbeddedOperatingSystems,69,进程的分类,第一种分类:

I/O-bound频繁的进行I/O通常会花费很多时间等待I/O操作的完成CPU-bound计算密集型需要大量的CPU时间进行运算,xlanchen2007.6.12,EmbeddedOperatingSystems,70,第二种分类交互式进程(interactiveprocess)需要经常与用户交互,因此要花很多时间等待用户输入操作响应时间要快,平均延迟要低于50150ms典型的交互式程序:

shell、文本编辑程序、图形应用程序等,xlanchen2007.6.12,EmbeddedOperatingSystems,71,批处理进程(batchprocess)不必与用户交互,通常在后台运行不必很快响应典型的批处理程序:

编译程序、科学计算实时进程(real-timeprocess)有实时需求,不应被低优先级的进程阻塞响应时间要短典型的实时进程:

视频/音频、机械控制等,xlanchen2007.6.12,EmbeddedOperatingSystems,72,与调度相关的系统调用,nicegetpriority/setprioritysched_getscheduler/sched_setschedulersched_getparam/sched_setparamsched_yieldsched_get_priority_min/sched_get_priority_maxsched_rr_get_interval,xlanchen2007.6.12,EmbeddedOpera

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 幼儿教育 > 幼儿读物

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2