linux 的 swapper 进程不能sleep,Linux进程管理与调度.ppt

Linux进程管理与调度 关于进程与线程Linux进程实现Linux进程调度策略Linux进程调度实现 1Linux进程与线程 Linux进程Linux线程 进程作为资源分配的基本单位而存在 线程作为调度的基本单位而存在我们都知道linux是不断发展的 在早期版本中 linux的基本调度单元是Task 只到现在 依然是它 在早期版本中 一个Task对应着一个进程 完全没有线程这个概念 随着时间的发展 线程的概念出现的 但是linux并没有马上接受这一概念 要知道 线程是现代操作系统的特征 向一个现有的操作系统内核引入线程是一件伤筋动骨的事情 更何况在线程概念的早期 受历史原因 UNIX 和硬件的限制 多核尚不是主流 线程的地位尚不确定 所以 linux并没有在内核中引入线程的概念 但是 linux提供了一个新的系统调用clone 通过该系统调用 内核中的多个进程可以共享一些信息 比如进程空间等 注意 此时linux内核的基础调度单元依然是Task 而且在内核看来 一个进程依然对应着一个Task 2Linux进程实现 Linux进程描述符也称进程控制块PCB shructtask struct unsignedlongstate 进程的状态 在2 6 23已经有9个状态unsignedlongpolicy 描述进程调度策略 判断是实时进程还是非实时进程structtask struct parent 组织进程的层次关系 指向父进程structlist headtasks 通过list head组织成双向链表pid tpid 每个进程唯一的标号 Linux进程描述符 在内核栈底创建新的结构structthread infoStructthread info structtask struct task structexec domain exec domain unsignedlongflags unsignedlongstatus u32cpu 在linux内核中 进程被分为两部分 一部分是thread info 保存在内核栈中 为了保持很小 因此只保存了必须的几个域 它有一个变量task 指向task struct 这个结构保存了进程相关的所有信息 而对应的task struct也保存了一个变量stack指向的就是一个thread union的联合体 Linux进程实现 相关的系统调用 fork 创建普通进程 copyonwrite 要复制父进程的页表 创建后子进程和父进程指向同一内存区域 仅当子进程有write发生时候 才会把改动的区域copy到子进程新的地址空间vfork 共享创建 完全无拷贝 子进程作为父进程的一个单独线程在其地址空间运行 父进程阻塞 clone 介于fork 和vfork 之间 可以指定共享什么 拷贝什么 说明 vfork 与clone 可用于创建新的内核线程 Linux进程实现 相关的函数 do fork 被clone fork vfork 调用 执行步骤如下 检查父进程标志是否为空 调用alloc task struct 为新进程分配一段内存空间 并将父进程描述符的内容拷贝到子进程 检查进程是否得到所需资源及系统当前允许的最大进程数 如进程需要引用内核模块 则增加模块引用计数 更新从父进程拷贝来的信息 系统调用get pid 将获得的pid赋给新建的子进程 更新不能由父进程继承的域 为新进程的执行设置跟踪进程的相关内核数据结构 新进程入链表 置新进程状态为task running 向父进程返回pid 说明 创建进程的系统调用返回时 ret from sys call 将根据存放系统调用返回值寄存器EAX的内容 pid 是0还是一个小正整数来决定是运行父进程还是子进程 在linux中第一个进程是内核进程 pid为0 它是所有的进程的父进程 这个进程也叫swapper 或者说是idle Linux进程状态 TASK RUNNING 进程在运行 是系统的当前进程 或者准备运行 等待被安排到系统的一个CPU上 TASK INTERRUPTIBLE 进程处于某个等待队列中 它能够被信号 signal 唤醒 等待资源的请求满足时 也被唤醒 TASK UNINTERRUPTIBLE 进程处于某个等待队列中 不能被信号或中断唤醒 只有等待的资源被满足时才被唤醒 TASK ZOMBIE 进程已经停止 但还没有释放进程控制块 TASK STOPPED 可能是被特定的信号终止 也可能是受其它进程的跟踪调用而暂时将CPU交给跟踪它的进程 Linux状态转换 scheduleranddispatcher 线程的实现在Linux系统中 线程被当作与其他进程共享某些资源的进程 线程的创建 与普通进程相似 需要指明共享资源 如 clone CLONE VM CLONE FS CLONE FILES CLONE SIGHAND 0 对比 clone SIGCHLD 0 普通的fork clone CLONE VFORK CLONE VM SIGCHLD 0 内核线程 内核进程没有独立的地址空间 只在内核空间运行 通常是一些后台执行的任务 通过clone 的参数 新创建的进程 也称为LWP Lightweightprocess 与父进程共享内存空间 文件句柄 信号处理等 从而达到创建线程相同的目的 5Linux进程调度策略 1 抢占式调度策略当一个进程进入TASK RUNNING状态 内核检查其优先级是否高于当前进程 当一个进程的时间片为0时 也会被抢占 抢占 用户抢占 need resched标志设置即发生 包括从系统调用返回用户空间 从中断处理程序返回用户空间的情况 内核抢占 为每个进程的thread info引入了preempt count计数器 该计数器初值为0 加锁时 其值加1 其数值为0时 内核可执行抢占 中断返回内核空间时产生 Linux进程调度策略 2 时间片调度策略内核根据时间片是否耗尽为标准 将就绪进程分为active expired两类 新创建的子进程和父进程均分父进程的剩余时间片时间片的计算以静态优先级为基础 即由task timeslice 函数根据静态优先级按照比例缩放 时间片的递减和重置在时钟中断中进行 sheduler tick 时间片计算 MIN TIMESLICE MAX TIMESLICE MIN TIMESLICE MAX PRIO 1 p static prio MAX USER PRIO 1 即 将100 139的优先级映射到200ms 10ms的时间片上 5Linux进程调度策略 3 优先级调度策略基于动态优先级的调度策略进程优先级取值范围 0 139 动态优先级prio根据静态优先级static prio变化 由effective prio 函数取得 该函数根据进程实际的睡眠平均时间分级成 5 0 5奖罚优先级值范围 用户赋予优先级nice转换为静态优先级 static prio 120 nice动态优先级设置时机 1 进程创建时2 唤醒休眠进程时 会修正进程的优先级3 在时钟中断中的schedule tick 中4 其他 IDLE进程初始化 负载平衡 修改nice值 修改调度策略 effective prio 函数 计算非实时进程的优先级 主要步骤如下 算出当前进程平均睡眠时间 得到进程的动态优先级 staticinteffective prio task t p if rt task p returnp prio bonus CURRENT BONUS p MAX BONUS 2 prio p static prio bonus returnprio 说明 系统通过一系列宏计算出bonus bonus 进程睡眠jiffers HZ 10 5 effective prio 函数 计算非实时进程的优先级 主要步骤如下 算出当前进程平均睡眠时间 得到进程的动态优先级 staticinteffective prio task t p if rt task p returnp prio bonus CURRENT BONUS p MAX BONUS 2 prio p static prio bonus returnprio 说明 系统通过一系列宏计算出bonus bonus 进程睡眠jiffers HZ 10 5 6Linux进程调度实现 可执行队列基本数据结构 runqueue定义在kernel sched c中structrunqueue spinlock tlock 运行队列自旋锁unsignedlongru running 任务数目 structprio array active 活动优先级队列structprio array expired 超时优先级队列structprio arrayarrays 2 实际优先级数组 Linux进程调度实现 优先级数组structprio array intnr active 任务数目unsignedlongbitmap BITMAP SIZE 优先级位图structlist headqueue MAX PRIO 优先级队列 说明 每个运行队列有2个优先级数组 一个活跃的 一个过期的 能够提供O 1 级算法复杂度的数据结构 Linux进程调度实现 优先级数组的重置通过维护2个优先级数组 active expired active数组上的进程还有剩余时间片 expired数组上的进程全部耗尽了时间片 当一个进程时间片到了会从active数组移到expired数组 而时间片事先计算好了 这里的重新计算时间片只需在两个数组之间切换即可 调度的实现 每个进程的进程描述符中与进程调度相关的域如下 volatilelongneed resched 确定是否需要重新调度的标志 unsignedlongpolicy 确定调度策略SCHED FIFO 先进先出的实时调度SCHED RR 基于优先级的循环轮转实时调度SCHED NORMAL 普通分时调度 rt priority 实时进程的优先级 0 99 nice 用户可控制的进程优先级因子 20 19 prio 进程的动态优先级static prio 进程的静态优先级sleep avg 进程的平均睡眠时间static prio MAX RT PRIO nice 20 schedule 函数功能 选择一个合适的进程运行 主要步骤清理当前运行进程选择下一个运行的进程设置新进程的运行环境执行进程上下文切换后期整理 直接启动调度 发生在当前进程因等待资源而需要进入被阻塞状态时 把当前进程放到适当的等待队列中把当前进程的state设为TASK INTERRUPTIBEL或者TASK UNINTERRUPTIBEL 调用schedule 准备让新的进程使用CPU 检查当前进程所需的资源是否可用 如果是 把当前进程从等待队列里删除 否则回到第2步 被动调度 need resched标志为1时执行 每次调入一个用户态进程之前 该变量的值均会被检查 来决定是否调用schedule 如果当前进程用完了其时间片 则调用update process times 函数重新计算 当一个进程被唤醒 且其优先级高于当前进程 wake up process 调用reschedule idle 设置当前进程的need resched 使被唤醒的进程尽快使用CPU 当sched setschedler 或sched yield 系统调用被调用时

展开阅读全文

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值