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 系统调用被调用时

展开阅读全文

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

  1. Linux进程描述符task_struct结构体详解--Linux进程的管理与调度(一)

    转自:http://blog.csdn.net/gatieme/article/details/51383272 日期 内核版本 架构 作者 GitHub CSDN 2016-05-12 Linux- ...

  2. Linux下0号进程的前世(init_task进程)今生(idle进程)----Linux进程的管理与调度(五)【转】...

    前言 Linux下有3个特殊的进程,idle进程(PID = 0), init进程(PID = 1)和kthreadd(PID = 2) idle进程由系统自动创建, 运行在内核态 idle进程其pi ...

  3. Linux进程调度器概述--Linux进程的管理与调度(十五)

    日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.6 X86 & arm gatieme LinuxDeviceDrivers Linux进程管理与调度 ...

  4. Linux进程描述符task struct结构体详解--Linux进程的管理与调度(一)

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 日期 内 ...

  5. linux里面有mysql的僵尸进程_Linux的僵尸进程处理1

    Linux中有两种异常的进程: 1.孤儿进程:应用通过fork进程后,父进程被kill或者exit,该父进程的子进程被1号进程接管.linux内核启动时候回启动0号进程,启动完毕后0号进程就处于空闲状 ...

  6. Linux进程ID号--Linux进程的管理与调度(三)

    进程ID概述 进程ID类型 要想了解内核如何来组织和管理进程ID,先要知道进程ID的类型: 内核中进程ID的类型用pid_type来描述,它被定义在include/linux/pid.h中 enum ...

  7. linux中怎么退出执行过程,(进程)处理过程中的Linux:从执行到退出

    Linux是一个多任务操作系统,表面上看,同时运行许多任务--即进程.每一个进程都在系统中留下足迹.这里介绍一些检查这些足迹的工具,并且还要说明蔓延的/proc目录到底是什么. 欢迎归来.上周我们考察 ...

  8. linux端口找进程,Linux查看端口、进程情况及kill进程的方法

    看端口: ps -aux | grep tomcat 发现并没有8080端口的Tomcat进程. 使用命令:netstat –apn 查看所有的进程和端口使用情况.发现下面的进程列表,其中最后一栏是P ...

  9. linux init进程是所有用户进程的祖先进程,Linux中init进程介绍及常用方法

    init(为英语:initialization的简写)是 Unix 和 类Unix 系统中用来产生其它所有进程的程序.它以守护进程的方式存在,其进程号为1. 所谓的init进程,它是一个由内核启动的用 ...

最新文章

  1. 伍六七带你学算法 入门篇-拼写单词
  2. [USACO08NOV]lites
  3. SQL Server 跨数据库事务
  4. [译]5.11. Functions and Variables Featured in This Chapter 本章的函数,变量和特性
  5. JavaScript调用其他函数中的变量
  6. python爬取js加载的数据_JS动态加载数据不会爬?老司机教你两个方法爬取想要的数据...
  7. Android Note-android studio 无法创建android项目
  8. JAVA 基础语法(四)——循环结构(while,do...while,for,break,continue)
  9. unity下载网页所有图片
  10. web的UI自动化实现步骤
  11. 【神经网络】一文读懂LSTM神经网络
  12. MySQL函数 思维导图
  13. ThinkPHP3.2中使用第三方库(phpQuery)
  14. 中南大学FYT机器人战队超级电容开发经验记录及分享(ROBOMASTER)
  15. 【FNN回归预测】基于matlab蝙蝠算法优化前馈神经网络数据回归预测【含Matlab源码 2070期】
  16. 鸿蒙harmonyOS怎么读取应用是否存在静默安装
  17. Copying File
  18. Java实现生产者消费者案例
  19. App打造自定义的统计SDK
  20. 【仓储管理系统需求分析(四)】

热门文章

  1. 如何比较两个文件是否完全一样,Windows、MacOS、Linux(使用自带命令比较)certutil,摘要,digest
  2. 女生学电气好还是学计算机好,电子电工专业怎么样 适合女生吗
  3. 高考考日语学计算机,日语是哪年纳入高考的,高考报日语选专业会受限吗
  4. 阿里社招面经分享!附上我的四面总结以及复习资料,希望对大家有帮助!
  5. ImportError: .xx/elsa/elsa_ext.cpython-37m-x86_64-linux-gnu.so: undefined symbol: _ZNK2at10TensorBas
  6. 通过Kuberneters Goat学习K8S安全(下)
  7. 我看了下GAAS里ROS里发布的pose 的 topic包含position和orientation,我觉得position是实际位置,orientation是期望位置。错了,是标准的里程计消息。
  8. java神湖兔子的面试题_面试题:兔子搬运萝卜
  9. ARIS 中的概念和表达法
  10. editplus注册码生成器