




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、嵌入式操作系统嵌入式操作系统陈香兰陈香兰Fall 2009进程(任务管理)进程(任务管理)Linux-2.6.2610/18/09嵌入式操作系统嵌入式操作系统3主要内容主要内容进程描述符进程切换进程的创建和删除10/18/09嵌入式操作系统嵌入式操作系统4进程的概念进程的概念进程是执行程序的一个实例进程和程序的区别几个进程可以并发的执行一个程序一个进程可以顺序的执行几个程序10/18/09嵌入式操作系统嵌入式操作系统5进程描述符进程描述符为了管理进程,内核必须对每个进程进行清晰的描述。进程描述符提供了内核所需了解的进程信息源码include/linux/sched.h定义struct task
2、_struct数据结构很庞大10/18/09嵌入式操作系统嵌入式操作系统6此图来自此图来自ULK3版,版,与与Linux-2.6.26已有不符已有不符仅作示意仅作示意10/18/09嵌入式操作系统嵌入式操作系统7Linux2.6进程的状态进程的状态简单过一下,与状态相关的一些宏简单过一下,与状态相关的一些宏1)组合状态)组合状态2)状态判断)状态判断3)状态设置)状态设置10/18/09嵌入式操作系统嵌入式操作系统8进程状态转换图进程状态转换图EXIT_ZOMBIE或者或者EXIT_DEAD或者或者TASK_DEAD10/18/09嵌入式操作系统嵌入式操作系统9标识一个进程标识一个进程使用进程
3、描述符地址进程和进程描述符之间有非常严格的一一对应关系,使得用32位进程描述符地址标识进程非常方便使用PID (Process ID,PID)每个进程的PID都存放在进程描述符的pid域中10/18/09嵌入式操作系统嵌入式操作系统10进程的进程的PID进程的pid字段Pid最大值,参见最大值,参见kernel/pid.c顺序使用顺序使用&循环使用循环使用include/linux/types.hinclude/asm-XXX/posix_typesYYY.hinclude/linux/threads.h10/18/09嵌入式操作系统嵌入式操作系统11stuct pid阅读includ
4、e/linux/pid.h中“What is struct pid?”10/18/09嵌入式操作系统嵌入式操作系统12Pid的管理和分配的管理和分配创建一个进程时,Pid名字空间do_forkcopy_processalloc_pidStruct pid的的cachePid位图位图关于名字空间的更多信息,参见:关于名字空间的更多信息,参见:Nsproxy.c以及以及pid_namespace.ch10/18/09嵌入式操作系统嵌入式操作系统13Init_pid_ns在在kernel_init中,被修改为中,被修改为init进程进程在在start_kernel中,调用中,调用pidmap_ini
5、t进行合理的初始化进行合理的初始化10/18/09嵌入式操作系统嵌入式操作系统14分配第一个位图页分配第一个位图页初始化初始化struct pid的的cache10/18/09嵌入式操作系统嵌入式操作系统15阅读alloc_pid、 alloc_pidmap函数10/18/09嵌入式操作系统嵌入式操作系统16进程和进程的进程和进程的内核内核堆栈堆栈Linux为每个进程分配一个8KB大小的内存区域,用于存放该进程两个不同的数据结构:Thread_info进程的内核堆栈进程处于内核态时使用,不同于用户态堆栈内核控制路径所用的堆栈很少,因此对栈和Thread_info来说,8KB足够了 Thread
6、_info 10/18/09嵌入式操作系统嵌入式操作系统17Thread_unionC语言允许用如下的一个union结构来方便的表示这样的一个混合体thread_info由体系结构相关部分定义由体系结构相关部分定义阅读阅读include/asm-arm/thread_info.h阅读阅读include/asm-x86/thread_info.h 以及以及include/asm-x86/thread_info_32.h10/18/09嵌入式操作系统嵌入式操作系统18进程描述符的分配/回收/访问Thread_info的分配/回收/访问alloc_thread_infofree_thread_inf
7、o10/18/09嵌入式操作系统嵌入式操作系统1910/18/09嵌入式操作系统嵌入式操作系统20从内核堆栈获得从内核堆栈获得thread_info根据thread_info描述符和内核态堆栈之间的配对,内核可以很容易的从堆栈寄存器的值获得thread_info的指针参见参见archarmkernelentry-header.S参见参见includeasm-armthread_info.h10/18/09嵌入式操作系统嵌入式操作系统21current宏进程描述符宏进程描述符includeasm-armCurrent.h10/18/09嵌入式操作系统嵌入式操作系统22Current宏的使用宏的使
8、用Current宏可以看成当前进程的进程描述符指针,在内核中直接使用比如current-pid返回在CPU上正在执行的进程的PID10/18/09嵌入式操作系统嵌入式操作系统23进程链表进程链表为了对给定类型的进程(比如所有在可运行状态下的进程)进行有效的搜索,内核维护了几个进程链表所有进程链表在进程描述符中:10/18/09嵌入式操作系统嵌入式操作系统24进程链表中的插入和删除使用常规list数据结构操作list_addlist_add_taillist_dellist_movelist_emptylist_for_eachlist_for_each_prevlist_for_each_sa
9、felist_for_each_entry参见参见include/linux/list.h或者或者lib/list_debug.c10/18/09嵌入式操作系统嵌入式操作系统25例如,在do_fork调用的copy_process中for_each_process宏扫描整个进程链表10/18/09嵌入式操作系统嵌入式操作系统26TASK_RUNNING状态的进程组织状态的进程组织入列出列等操作:dequeue_taskenqueue_taskconst struct sched_class,调度类rt_sched_classfair_sched_classidle_sched_class每个每
10、个cpu有一个运行队列有一个运行队列关于调度的描述,关于调度的描述,参见参见sched_coding.txt和和sched-design-CFS.txt10/18/09嵌入式操作系统嵌入式操作系统27运行队列数据结构运行队列数据结构10/18/09嵌入式操作系统嵌入式操作系统28struct cfs_rq红黑树红黑树10/18/09嵌入式操作系统嵌入式操作系统29struct rt_rq基于优先级的运行队列基于优先级的运行队列10/18/09嵌入式操作系统嵌入式操作系统3010/18/09嵌入式操作系统嵌入式操作系统3110/18/09嵌入式操作系统嵌入式操作系统32调度类调度类 阅读调度类s
11、ched_class的定义源码 找到主要与运行队列有关的 enqueue_task、dequeue_task Idle相关:idle_sched_class no enqueue/yield_task for idle tasks dequeue_task_idle Fair相关 enqueue_task_fair dequeue_task_fair Rt相关 enqueue_task_rt dequeue_task_rt10/18/09嵌入式操作系统嵌入式操作系统33Idle类特殊类特殊10/18/09嵌入式操作系统嵌入式操作系统34Fair类类进而查看进而查看1)enqueue_entit
12、y2)_enqueue_entity(红黑树)(红黑树)3)sched_entity结构结构4) struct rq5)struct cfs_rqCompletely Fair Scheduler 完全公平调度完全公平调度10/18/09嵌入式操作系统嵌入式操作系统35Rt类类进而查看:进而查看:1)enqueue_rt_entity2)_enqueue_rt_entity每个每个cpu有一个队列有一个队列3)sched_rt_entity4)struct rq5)struct rt_rq6) struct rt_prio_array优先级队列优先级队列10/18/09嵌入式操作系统嵌入式操作
13、系统36激活一个任务activate_task相对的:相对的:deactivate_task10/18/09嵌入式操作系统嵌入式操作系统37pidhash表及链接表表及链接表在一些情况下,内核必须能从进程的PID得出对应的进程描述符指针。例如kill系统调用为了加速查找,引入了pid_hash散列表初始化:初始化:pidhash_initHash函数的使用情况函数的使用情况10/18/09嵌入式操作系统嵌入式操作系统38Task_struct中:中:可以从进程描述符得到进程的可以从进程描述符得到进程的pid相关信息相关信息10/18/09嵌入式操作系统嵌入式操作系统39Pid数据结构数据结构2
14、.6内核为PID专门引入了一个数据结构,Why?独立的进程;进程组;sessions使用pid数字的注意之处考虑进程的删除和创建10/18/09嵌入式操作系统嵌入式操作系统40pidhash表及链接表表及链接表10/18/09嵌入式操作系统嵌入式操作系统41进程之间的亲属关系进程之间的亲属关系程序创建的进程具有父子关系,在编程时往往需要引用这样的父子关系。进程描述符中有几个域用来表示这样的关系10/18/09嵌入式操作系统嵌入式操作系统42等待队列等待队列 当要把除了TASK_RUNNING状态之外的进程组织在一起时,linux使用了等待队列 TASK_INTERRUPTIBLE和TASK_U
15、NINTERRUPTIBLE状态的进程再分成很多类,每一类对应一个特定的事件。在这种情况下,进程状态提供的信息满足不了快速检索,因此,内核引进了另外的进程链表,叫做等待队列 等待队列在内核中有很多用途,尤其是对中断处理、进程同步和定时用处很大10/18/09嵌入式操作系统嵌入式操作系统43等待队列使得进程可以在事件上的条件等待,并且当等待的条件为真时,由内核唤醒它们等待队列由循环链表实现阅读相关的宏阅读相关的宏10/18/09嵌入式操作系统嵌入式操作系统44在等待队列上内核实现了一些操作函数add_wait_queue add_wait_queue_exclusiveremove_wait_q
16、ueue10/18/09嵌入式操作系统嵌入式操作系统45进程等待进程等待等待一个特定事件的进程能调用下面几个函数中的任一个sleep_onsleep_on_timeoutinterruptible_sleep_oninterruptible_sleep_on_timeout进程等待由需要等待的进程自己进行(调用)10/18/09嵌入式操作系统嵌入式操作系统46sleep_on相当于相当于阅读实际的阅读实际的sleep_on代码代码10/18/09嵌入式操作系统嵌入式操作系统47此外,还可能按照如下方式进行sleep10/18/09嵌入式操作系统嵌入式操作系统48例如事件等待wait_event
17、_wait_event等待,直到事件发生(有效,或等待,直到事件发生(有效,或)10/18/09嵌入式操作系统嵌入式操作系统49进程的进程的唤醒唤醒利用wake_up或者wake_up_interruptible等一系列的宏,都让插入等待队列中的进程进入TASK_RUNNING状态10/18/09嵌入式操作系统嵌入式操作系统50_wake_up_wake_up_common间接间接default_wake_functionactivate_tasktry_to_wake_up10/18/09嵌入式操作系统嵌入式操作系统51进程切换进程切换(process switching)为了控制进程的执行
18、,内核必须有能力挂起正在CPU上执行的进程,并恢复以前挂起的某个进程的执行,这叫做进程切换,任务切换,上下文切换10/18/09嵌入式操作系统嵌入式操作系统52进程上下文进程上下文包含了进程执行需要的所有信息用户地址空间包括程序代码,数据,用户堆栈等控制信息进程描述符,内核堆栈等硬件上下文10/18/09嵌入式操作系统嵌入式操作系统53硬件上下文硬件上下文尽管每个进程可以有自己的地址空间,但所有的进程只能共享CPU的寄存器。因此,在恢复一个进程执行之前,内核必须确保每个寄存器装入了挂起进程时的值。这样才能正确的恢复一个进程的执行硬件上下文:进程恢复执行前必须装入寄存器的一组数据包括通用寄存器的
19、值以及一些系统寄存器通用寄存器系统寄存器与具体的体系结构相关与具体的体系结构相关10/18/09嵌入式操作系统嵌入式操作系统54在linux中一个进程的上下文主要保存在thread_info,task_struct的thread_struct中,其他信息放在内核态堆栈中10/18/09嵌入式操作系统嵌入式操作系统55thread_info ,体系结构相关,体系结构相关10/18/09嵌入式操作系统嵌入式操作系统56cpu_context_save10/18/09嵌入式操作系统嵌入式操作系统57Thread_structthread_struct也是体系结构相关的,参见各体系结构头文件的pros
20、sor.h在在task_struct中中10/18/09嵌入式操作系统嵌入式操作系统58Pt_regs用户态用户态/内核态内核态 切换切换10/18/09嵌入式操作系统嵌入式操作系统59上下文切换上下文切换switch_to宏执行进程切换,schedule()函数通过调用context_switch,间接调用这个宏(体系结构相关,在system.h/system_32.h/system_64.h中定义)switch_to利用了prev和next两个参数:prev:指向当前进程next:指向被调度的进程10/18/09嵌入式操作系统嵌入式操作系统6010/18/09嵌入式操作系统嵌入式操作系统6
21、1回顾回顾cpu_context_save结构结构10/18/09嵌入式操作系统嵌入式操作系统62进程切换的关键语句进程切换的关键语句堆栈的切换从此,内核对next的内核态堆栈操作,因此,这条指令执行从prev到next真正的上下文切换,因为thread_info和内核态堆栈紧密联系在一起,改变内核态堆栈就意味改变当前thread_info10/18/09嵌入式操作系统嵌入式操作系统63什么时候next进程真正开始执行呢?10/18/09嵌入式操作系统嵌入式操作系统64?哪里切换了进程的地址空间?哪里切换了进程的地址空间10/18/09嵌入式操作系统嵌入式操作系统65主要内容主要内容进程描述符
22、进程切换进程的创建和删除进程的创建和删除10/18/09嵌入式操作系统嵌入式操作系统66进程的创建进程的创建许多进程可以并发的运行同一程序,这些进程共享内存中程序正文的单一副本,但每个进程有自己的单独的数据和堆栈区一个进程可以在任何时刻可以执行新的程序,并且在它的生命周期中可以运行几个程序又如,只要用户输入一条命令,shell进程就创建一个新进程10/18/09嵌入式操作系统嵌入式操作系统67Linux提供了几个系统调用来创建和终止进程,以及执行新程序 Fork,vfork和clone系统调用创建新进程 exec系统调用执行一个新程序 exit系统调用终止进程(进程也可以因收到信号而终止)10
23、/18/09嵌入式操作系统嵌入式操作系统68fork fork系统调用创建一个新进程 调用fork的进程称为父进程 新进程是子进程 子进程几乎就是父进程的完全复制。它的地址空间是父进程的复制,一开始也是运行同一程序。 fork系统调用为父子进程返回不同的值10/18/09嵌入式操作系统嵌入式操作系统69exec 很多情况下,子进程从fork返回后很多会调用exec来开始执行新的程序 这种情况下,子进程根本不需要读或者修改父进程拥有的所有资源。 所以fork中地址空间的复制依赖于Copy On Write技术,降低fork的开销10/18/09嵌入式操作系统嵌入式操作系统70写时复制技术写时复制
24、技术写时复制技术允许父子进程能读相同的物理页。只要两者有一个进程试图写一个物理页,内核就把这个页的内容拷贝到一个新的物理页,并把这个新的物理页分配给正在写的进程10/18/09嵌入式操作系统嵌入式操作系统71使用使用fork和和exec的例子的例子If (result = fork() = 0)/* 子进程代码 */if (execve(“new_program”,)0)perror(“execve failed”);exit(1);else if (result0)perror(“fork failed”)/* result=子进程的pid,父进程将会从这里继续执行*/10/18/09嵌入式
25、操作系统嵌入式操作系统72 分开这两个系统调用是有好处的 比如服务器可以fork许多进程执行同一个程序 有时程序只是简单的exec,执行一个新程序 在fork和exec之间,子进程可以有选择的执行一系列操作以确保程序以所希望的状态运行 重定向输入输出 关闭不需要的打开文件 改变UID或是进程组 重置信号处理程序 若单一的系统调用试图完成所有这些功能将是笨重而低效的 现有的fork-exec框架灵活性更强 清晰,模块化强10/18/09嵌入式操作系统嵌入式操作系统73do_fork不论是fork,vfork还是clone,在内核中最终都调用了do_fork10/18/09嵌入式操作系统嵌入式操作
26、系统74阅读do_fork; copy-process; 了解大致程序流程?子进程从哪里开始执行,它的返回值是什么?阅读copy_thread(arch/arm/kernel/process.c)复制父进程的堆栈?父进程的堆栈中有些什么?Fork系统调用?10/18/09嵌入式操作系统嵌入式操作系统75返回值被强制写010/18/09嵌入式操作系统嵌入式操作系统76子进程的内核态堆栈子进程的内核态堆栈Thread_info子进程的8K unionesp返回值被强制写0用户态堆栈sp的值用户态下pc的值子进程恢复到用户态时需要的上下文pcsp子进程的硬件上下文ret_from_fork低地址高地
27、址10/18/09嵌入式操作系统嵌入式操作系统77子进程的执行子进程的执行fork后,子进程处于可运行状态,由调度器决定何时把CPU交给这个子进程进程切换后因为pc指向ret_from_fork,所以CPU立刻跳转到ret_from_fork()去执行。接着这个函数调用ret_from_sys_call(),此函数用存放在栈中的值装载所有寄存器,并强迫CPU返回用户态10/18/09嵌入式操作系统嵌入式操作系统7810/18/09嵌入式操作系统嵌入式操作系统7910/18/09嵌入式操作系统嵌入式操作系统80关于关于pt_regs结构的说明结构的说明10/18/09嵌入式操作系统嵌入式操作系统
28、8110/18/09嵌入式操作系统嵌入式操作系统82内核线程内核线程系统把一些重要的任务委托给周期性执行的进程刷新磁盘高速缓存交换出不用的页框维护网络链接等待内核线程与普通进程的差别每个内核线程执行一个单独指定的内核函数只运行在内核态只使用大于PAGE_OFFSET的线性地址空间10/18/09嵌入式操作系统嵌入式操作系统83例如,例如,0号进程创建号进程创建1号进程号进程init10/18/09嵌入式操作系统嵌入式操作系统84线程和进程的比较线程和进程的比较Linux内核中没有线程的概念没有针对所谓线程的调度策略没有数据结构用来表示一个线程一般线程的概念在linux中只是表现为一组共享资源的
29、进程(每个这样的进程都有自己的进程描述符)在其他系统中(比如windows)线程是实实在在的一种运行抽象,提供了比进程更轻更快的调度单元在linux中“线程”仅仅是表示多个进程共享资源的一种说法10/18/09嵌入式操作系统嵌入式操作系统85创建内核线程创建内核线程Kerenl_thread()创建一个内核线程,并且只能由另一个内核线程来执行这个调用10/18/09嵌入式操作系统嵌入式操作系统8610/18/09嵌入式操作系统嵌入式操作系统87进程树进程树进程0进程110/18/09嵌入式操作系统嵌入式操作系统88进程进程0 所有进程的祖先叫做进程0 在系统初始化阶段由start_kernel
30、()函数从无到有手工创建的一个内核线程 Init_task Init_thread_union 进程0最后的初始化工作创建init内核线程,此后运行cpu_idle,成为idle进程10/18/09嵌入式操作系统嵌入式操作系统89进程进程1又称为init进程由进程0在start_kernel调用rest_init创建init进程PID为1,当调度程序选择到init进程时,init进程开始执行kernel_init ()函数10/18/09嵌入式操作系统嵌入式操作系统90kernel_init() 为常规内核任务初始化一些必要的内核线程,如:kflushd 刷新脏缓冲区中的内容到磁盘以归还内存kswapd 执行内
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 抗疫课件教学课件
- 抗凝药物课件
- 2025年医用消毒灭菌设备项目合作计划书
- 2025年呼吸科护理考试题及答案
- 戚佳丽课件教学课件
- 2025年建行考试笔试题目及答案
- 美术中招考试题及答案
- 装火车工考试题及答案
- 企业管理考试真题及答案
- 司法考试综合题及答案
- 测绘保密自查管理制度
- 2026高考作文备考之题目解析及范文素材:觉醒是一种持续的心态
- 2025年《网络营销》课程标准
- DB32-T 5092-2025 低压分布式光伏接入电网数据采集要求
- 2025年中国微网雾化器行业市场前景预测及投资价值评估分析报告
- T/CCS 004-2023智能化煤矿体系架构
- 即墨区离婚协议书
- 别墅设计全套方案
- 科研项目经费管理
- 焊接生产与管理
- 《经济法基础》课件-第七章 税收法律制度
评论
0/150
提交评论