linux代码导读-进程管理_第1页
linux代码导读-进程管理_第2页
linux代码导读-进程管理_第3页
linux代码导读-进程管理_第4页
linux代码导读-进程管理_第5页
已阅读5页,还剩58页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Linux内核源代码导读中国科学技术大学计算机系陈香兰(0551-3606864)xlanchen@/~xlanchen

Spring2009进程(任务管理)主要内容进程描述符进程切换进程的创建和删除2/2/20233Linux内核源代码导读进程的概念进程是执行程序的一个实例进程和程序的区别 几个进程可以并发的执行一个程序一个进程可以顺序的执行几个程序2/2/20234Linux内核源代码导读进程描述符为了管理进程,内核必须对每个进程进行清晰的描述。进程描述符提供了内核所需了解的进程信息源码include/linux/sched.h定义

structtask_struct数据结构很庞大2/2/20235Linux内核源代码导读stack2/2/20236Linux内核源代码导读Linux2.6进程的状态简单过一下,与状态相关的一些宏1)组合状态2)状态判断3)状态设置2/2/20237Linux内核源代码导读进程状态转换图EXIT_ZOMBIE或者EXIT_DEAD或者TASK_DEAD2/2/20238Linux内核源代码导读标识一个进程使用进程描述符地址进程和进程描述符之间有非常严格的一一对应关系,使得用32位进程描述符地址标识进程非常方便使用PID(ProcessID,PID)每个进程的PID都存放在进程描述符的pid域中2/2/20239Linux内核源代码导读进程和进程的内核堆栈Linux为每个进程分配一个8KB大小的内存区域,用于存放该进程两个不同的数据结构:Thread_info进程的内核堆栈进程处于内核态时使用

不同于用户态堆栈内核控制路径所用的堆栈

很少,因此对栈和描述符

来说,8KB足够了Thread_info2/2/202310Linux内核源代码导读Thread_unionC语言允许用如下的一个union结构来方便的表示这样的一个混合体2/2/202311Linux内核源代码导读进程描述符的分配/回收/访问Thread_info的分配/回收/访问alloc_thread_infofree_thread_info2/2/202312Linux内核源代码导读2/2/202313Linux内核源代码导读从当前内核堆栈获得当前thread_info根据thread_info描述符和内核态堆栈之间的配对,内核可以很容易的从esp寄存器的值获得当前在CPU上运行的进程的描述符指针因为这个内存区是8KB=213大小,内核必须做的就是让esp有13位的有效位,以获得thread_info的基地址2/2/202314Linux内核源代码导读current宏进程描述符2/2/202315Linux内核源代码导读可知,从每个cpu相关参数中,把per_cpu__current_task,取出返回需要找到该参数的赋值之处!!2/2/202316Linux内核源代码导读考虑对应的x86_write_percpu的使用情况在__switch_to中被调用2/2/202317Linux内核源代码导读Current宏的使用Current宏可以看成当前进程的进程描述符指针,在内核中直接使用比如current->pid返回在CPU上正在执行的进程的PID2/2/202318Linux内核源代码导读进程的PID进程的pid字段Pid最大值2/2/202319Linux内核源代码导读Pid的管理和分配创建一个进程时,Pid名字空间do_forkcopy_processalloc_pidStructpid的cache2/2/202320Linux内核源代码导读Pid位图Pid数据结构对pid名字空间:2.6内核为PID专门引入了一个数据结构,Why?

独立的进程;进程组;sessions

使用pid数字的注意之处考虑进程的删除和创建2/2/202321Linux内核源代码导读最初的pid名字空间在kernel_init中,被修改为init进程在start_kernel中,调用pidmap_init进行合理的初始化2/2/202322Linux内核源代码导读分配第一个位图页初始化structpid的cache2/2/202323Linux内核源代码导读2.6内核为PID专门引入了一个数据结构Why?独立的进程;进程组;sessions使用pid数字的注意之处考虑进程的删除和创建2/2/202324Linux内核源代码导读阅读alloc_pid、alloc_pidmap函数2/2/202325Linux内核源代码导读进程链表为了对给定类型的进程(比如所有在可运行状态下的进程)进行有效的搜索,内核维护了几个进程链表所有进程链表在进程描述符中:2/2/202326Linux内核源代码导读进程链表中的插入和删除使用常规list数据结构操作2/2/202327Linux内核源代码导读list_addlist_add_taillist_dellist_movelist_emptylist_for_eachlist_for_each_prevlist_for_each_safelist_for_each_entry…2/2/202328Linux内核源代码导读例如,在do_fork调用的copy_process中for_each_process宏扫描整个进程链表2/2/202329Linux内核源代码导读TASK_RUNNING状态的进程组织对可运行队列的一些操作函数底层:常规的list数据结构操作入列出列等操作:dequeue_taskenqueue_taskconststructsched_class,调度类rt_sched_classfair_sched_classidle_sched_class每个cpu有一个运行队列关于调度的描述,参见sched_coding.txt和sched-design-CFS.txt2/2/202330Linux内核源代码导读运行队列数据结构2/2/202331Linux内核源代码导读structcfs_rq……红黑树2/2/202332Linux内核源代码导读structrt_rq……基于优先级的运行队列2/2/202333Linux内核源代码导读2/2/202334Linux内核源代码导读2/2/202335Linux内核源代码导读调度类阅读调度类sched_class的定义源码找到主要与运行队列有关的enqueue_task、dequeue_taskIdle相关:idle_sched_classnoenqueue/yield_taskforidletasksdequeue_task_idleFair相关enqueue_task_fairdequeue_task_fairRt相关enqueue_task_rtdequeue_task_rt2/2/202336Linux内核源代码导读Idle类特殊2/2/202337Linux内核源代码导读Fair类进而查看1)enqueue_entity2)__enqueue_entity

(红黑树)3)sched_entity结构4)structrq5)structcfs_rqCompletelyFairScheduler完全公平调度2/2/202338Linux内核源代码导读Rt类进而查看:1)enqueue_rt_entity2)__enqueue_rt_entity 每个cpu有一个队列3)sched_rt_entity4)structrq5)structrt_rq6)structrt_prio_array优先级队列2/2/202339Linux内核源代码导读激活一个任务activate_task相对的:deactivate_task2/2/202340Linux内核源代码导读pidhash表及链接表在一些情况下,内核必须能从进程的PID得出对应的进程描述符指针。例如kill系统调用为了加速查找,引入了pid_hash散列表初始化:pidhash_initTask_struct中:2/2/202341Linux内核源代码导读pidhash表及链接表2/2/202342Linux内核源代码导读进程之间的亲属关系程序创建的进程具有父子关系,在编程时往往需要引用这样的父子关系。进程描述符中有几个域用来表示这样的关系2/2/202343Linux内核源代码导读等待队列当要把除了TASK_RUNNING状态之外的进程组织在一起时,linux使用了等待队列TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE状态的进程再分成很多类,每一类对应一个特定的事件。在这种情况下,进程状态提供的信息满足不了快速检索,因此,内核引进了另外的进程链表,叫做等待队列等待队列在内核中有很多用途,尤其是对中断处理、进程同步和定时用处很大2/2/202344Linux内核源代码导读等待队列使得进程可以在事件上的条件等待,并且当等待的条件为真时,由内核唤醒它们等待队列由循环链表实现阅读相关的宏2/2/202345Linux内核源代码导读在等待队列上内核实现了一些操作函数add_wait_queueadd_wait_queue_exclusiveremove_wait_queue2/2/202346Linux内核源代码导读进程等待等待一个特定事件的进程能调用下面几个函数中的任一个sleep_onsleep_on_timeoutinterruptible_sleep_oninterruptible_sleep_on_timeout进程等待由需要等待的进程自己进行(调用)2/2/202347Linux内核源代码导读sleep_on相当于阅读实际的sleep_on代码2/2/202348Linux内核源代码导读此外,还可能按照如下方式进行sleep2/2/202349Linux内核源代码导读例如事件等待wait_event__wait_event等待,直到事件发生(有效,或…)2/2/202350Linux内核源代码导读进程的唤醒利用wake_up或者wake_up_interruptible等一系列的宏,都让插入等待队列中的进程进入TASK_RUNNING状态2/2/202351Linux内核源代码导读__wake_up__wake_up_common 间接default_wake_functionactivate_tasktry_to_wake_up2/2/202352Linux内核源代码导读进程切换(processswitching)为了控制进程的执行,内核必须有能力挂起正在CPU上执行的进程,并恢复以前挂起的某个进程的执行,这叫做进程切换,任务切换,上下文切换2/2/202353Linux内核源代码导读进程上下文包含了进程执行需要的所有信息用户地址空间

包括程序代码,数据,用户堆栈等控制信息

进程描述符,内核堆栈等硬件上下文2/2/202354Linux内核源代码导读硬件上下文尽管每个进程可以有自己的地址空间,但所有的进程只能共享CPU的寄存器。因此,在恢复一个进程执行之前,内核必须确保每个寄存器装入了挂起进程时的值。这样才能正确的恢复一个进程的执行硬件上下文:

进程恢复执行前必须装入寄存器的一组数据包括通用寄存器的值以及一些系统寄存器通用寄存器系统寄存器2/2/202355Linux内核源代码导读在linux中一个进程的上下文主要保存在thread_info,

task_struct的thread_struct中,其他信息放在内核态堆栈中2/2/202356Linux内核源代码导读thread_info2/2/202357Linux内核源代码导读Thread_struct……2/2/202358Linux内核源代码导读Pt_regs2/2/202359Linux内核源代码导读上下文切换switch_to宏执行进程切换,schedule()函数通过调用context_switch,间接调用这个宏一调度一个新的进程在CPU上运行switch_to利用了prev

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论