linux进程管理与调度

上传人:shaoy****1971 文档编号:111940982 上传时间:2019-11-04 格式:PPT 页数:25 大小:225.50KB
返回 下载 相关 举报
linux进程管理与调度_第1页
第1页 / 共25页
linux进程管理与调度_第2页
第2页 / 共25页
linux进程管理与调度_第3页
第3页 / 共25页
linux进程管理与调度_第4页
第4页 / 共25页
linux进程管理与调度_第5页
第5页 / 共25页
点击查看更多>>
资源描述

《linux进程管理与调度》由会员分享,可在线阅读,更多相关《linux进程管理与调度(25页珍藏版)》请在金锄头文库上搜索。

1、Linux进程管理与调度 关于进程与线程 Linux进程实现 Linux进程调度策略 Linux进程调度实现 1 Linux进程与线程 Linux进程 Linux线程 进程作为资源分配的基本单位而存在,线程作为调度的基本单位而存在 我们都知道linux是不断发展的.在早期版本中, linux的基本调度单元是Task, 只到现在, 依然是它. 在早期版本中, 一个Task对应着一个进程, 完全没有线程这个概念. 随着时间的发展, 线程的概念出现的, 但是linux并没有马上接受这一概念, 要知道, 线程是现代操作系统的特征, 向一个现有的操作系统内核引入线程是一件伤筋 动骨的事情, 更何况在线程

2、概念的早期, 受历史原因(UNIX)和硬件的限制(多核 尚不是主流), 线程的地位尚不确定. 所以, linux并没有在内核中引入线程的概 念. 但是, linux提供了一个新的系统调用clone, 通过该系统调用, 内核中的多个进程 可以共享一些信息, 比如进程空间等. 注意, 此时linux内核的基础调度单元依然 是Task, 而且在内核看来, 一个进程依然对应着一个Task. 2 Linux进程实现 Linux进程描述符也称 进程控制块PCB: shruct task_struct unsigned long state; /进程的状态,在2.6.23已经有9个状态 unsigned l

3、ong policy; /描述进程调度策略.判断是实时进程还是非实时进程 struct task_struct *parent; /组织进程的层次关系,指向父进程 struct list_head tasks; /通过list_head组织成双向链表 pid_t pid; /每个进程唯一的标号 ; Linux进程描述符 在内核栈底创建新的结构struct thread_info Struct thread_info struct task_struct *task; struct exec_domain *exec_domain; unsigned long flags; unsigned l

4、ong status; _u32 cpu; ; 在linux内核中,进程被分为两部分,一部分是thread_info,保存在内核栈中,为了保持很小, 因此只保存了必须的几个域,它有一个变量task,指向task_struct,这个结构保存了进程相关的 所有信息。而对应的task_struct也保存了一个变量stack指向的就是一个thread_union的联合体 Linux进程实现相关的系统调用 fork(): 创建普通进程,copy on write(要复制父进程的页表) 创建后子进程和父进程指向同一内存区域,仅当子进程有 write发生时候,才会把改动的区域copy到子进程新的地址空 间

5、vfork(): 共享创建,完全无拷贝。(子进程作为父进程的一个单独 线程在其地址空间运行,父进程阻塞) clone(): 介于fork()和vfork()之间,可以指定共享什么,拷贝什么。 说明:vfork()与clone()可用于创建新的内核线程。 Linux进程实现相关的函数 do_fork():/ 被clone(),fork(),vfork()调用,执行步骤如下: 检查父进程标志是否为空。 调用alloc_task_struct()为新进程分配一段内存空间,并将父 进程描述符的内容拷贝到子进程。 检查进程是否得到所需资源及系统当前允许的最大进程数 。 如进程需要引用内核模块,则增加模块

6、引用计数。 更新从父进程拷贝来的信息。 系统调用get_pid(),将获得的pid赋给新建的子进程。 更新不能由父进程继承的域。 为新进程的执行设置跟踪进程的相关内核数据结构,新进 程入链表。 置新进程状态为task_running, 。 向父进程返回pid。 说明: 创建进程的系统调用返回时(ret_from_sys_call),将根 据存放系统调用返回值寄存器EAX的内容(pid)是0还是一个小 正整数来决定是运行父进程还是子进程。 在linux中第一个进程是内核进程,pid为0,它是所有的进程 的父进程。这个进程也叫swapper,或者说是idle. Linux进程状态 TASK_RUN

7、NING:进程在运行 ( 是系统的当前进程 ) 或 者准备运行(等待被安排到系统的一个CPU上)。 TASK_INTERRUPTIBLE:进程处于某个等待队列中,它 能够被信号(signal)唤醒。等待资源的请求满足时,也被 唤醒。 TASK_UNINTERRUPTIBLE:进程处于某个等待队列中 ,不能被信号或中断唤醒,只有等待的资源被满足时才被唤 醒。 TASK_ZOMBIE: 进程已经停止,但还没有释放进程控制 块。 TASK_STOPPED:可能是被特定的信号终止,也可能是 受其它进程的跟踪调用而暂时将CPU交给跟踪它的进程。 Linux状态转换 scheduler and dispa

8、tcher 线程的实现 在Linux系统中,线程被当作与其他进程共享某些资源的进程. 线程的创建:与普通进程相似,需要指明共享资源。 如:clone (CLONE_VM | CLONE_FS | CLONE_FILES|CLONE_SIGHAND,0); 对比:clone (SIGCHLD, 0) /普通的fork() clone (CLONE_VFORK | CLONE_VM | SIGCHLD, 0) 内核线程:内核进程没有独立的地址空间,只在内核空间运 行。通常是一些后台执行的任务。 通过clone()的参数,新创建的进程,也称为LWP(Lightweight process)与父进程共

9、享内存空间,文件句柄,信号处理等,从 而达到创建线程相同的目的。 5 Linux进程调度策略 1) 抢占式调度策略 当一个进程进入TASK_RUNNING状态,内核检查其优先级 是否高于当前进程。 当一个进程的时间片为0时,也会被抢占。 抢占: 用户抢占:need_resched标志设置即发生,包括从系统调用返回用户空间 、 从中断处理程序返回用户空间的情况。 内核抢占:为每个进程的thread_info引入了preempt_count计数器,该计数 器初值为0,加锁时,其值加1,其数值为0时,内核可执行抢 占。中断返回内核空间时产生。 Linux进程调度策略 2) 时间片调度策略 内核根据时

10、间片是否耗尽为标准,将就绪进程分为active, expired两类。 新创建的子进程和父进程均分父进程的剩余时间片 时间片的计算以静态优先级为基础,即由task_timeslice()函数根据静态优 先级按照比例缩放。 时间片的递减和重置在时钟中断中进行,sheduler_tick() 时间片计算: MIN_TIMESLICE+(MAX_TIMESLICE MIN_TIMESLICE)*(MAX_PRIO-1 -(p)-static_prio)/(MAX_USER_PRIO-1) 即:将100139的优先级映射到200ms10ms的时间片上 5 Linux进程调度策略 3) 优先级调度策略

11、基于动态优先级的调度策略 进程优先级取值范围:0139,动态优先级prio根据静态优先级static_prio 变化,由effective_prio()函数取得,该函数根据进程实际的睡眠平均时间 分级成-50+5奖罚优先级值范围。 用户赋予优先级nice转换为静态优先级:static_prio=120+nice 动态优先级设置时机: 1)进程创建时 2)唤醒休眠进程时,会修正进程的优先级 3)在时钟中断中的schedule_tick()中 4)其他:IDLE进程初始化、负载平衡、修改nice值、修改调度策略 effective_prio()函数: 计算非实时进程的优先级,主要步骤如下: 算出当

12、前进程平均睡眠时间。 得到进程的动态优先级。 static int effective_prio(task_t *p) if (rt_task(p) return p- prio; bonus = CURRENT_BONUS(p) MAX_BONUS / 2; prio = p-static_prio bonus; return prio; 说明:系统通过一系列宏计算出bonus. bonus = (进程睡眠jiffers/HZ )*10 - 5 effective_prio()函数: 计算非实时进程的优先级,主要步骤如下: 算出当前进程平均睡眠时间。 得到进程的动态优先级。 static i

13、nt effective_prio(task_t *p) if (rt_task(p) return p- prio; bonus = CURRENT_BONUS(p) MAX_BONUS / 2; prio = p-static_prio bonus; return prio; 说明:系统通过一系列宏计算出bonus. bonus = (进程睡眠jiffers/HZ )*10 - 5 6 Linux进程调度实现 可执行队列 基本数据结构:runqueue 定义在kernel/sched.c中 struct runqueue spinlock_t lock; /运行队列自旋锁 unsigned

14、 long ru_running; /任务数目 struct prio_array *active; /活动优先级队列 struct prio_array *expired; /超时优先级队列 struct prio_array arrays2; /实际优先级数组 Linux进程调度实现 优先级数组 struct prio_array int nr_active; /任务数目 unsigned long bitmapBITMAP_SIZE;/优先级位图 struct list_head queueMAX_PRIO;/优先级队列 说明:每个运行队列有2个优先级数组,一个活跃的,一个过 期的。能够

15、 提供 O(1)级算法复杂度的数据结构。 Linux进程调度实现 优先级数组的重置 通过维护2个优先级数组,active,expired, active数组上的进程还有剩余时间片 ,expired数组上的进程全部耗尽了时间片。 当一个进程时间片到了会从active数组移到expired数组,而时间片事先计算 好了,这里的重新计算时间片只需在两个数组之间切换即可。 调度的实现 每个进程的进程描述符中与进程调度相关的域如下: volatile long need_resched; 确定是否需要重新调度的标志 。 unsigned long policy; 确定调度策略 SCHED_FIFO /先进先出的实时调度 SCHED_RR /基于优先级的循环轮转实时调度 SCHED_NORMAL /普通分时调度 rt_priority;实时进程的优先级(099) nice:用户可控制的进程优先级因子。(-2019) prio : 进程的动态优先级 static_prio: 进程的静态优先级 sleep_avg: 进程的平均睡眠时

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 中学教育 > 职业教育

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