【8】Linux-进程管理子系统

Linux-进程管理

程序:存放在磁盘上的一系列代码和数据的可执行映像,是一个静止的实体

进程:一个执行中的程序,是动态的实体

进程四要素

1.有一段程序供其执行,这段程序不一定是某个进程所专有,可以与其他进程共用。

2.有进程专用的内核空间堆栈

3.在内核中有一个task_struct数据结构,即PCB(process control block),进程控制块,有了这个数据结构,进程才能成为内核调度的一个基本单位接受内核的调度。

4.有独立的用户空间

 

Linux的进程状态

 


1.TASK_RUNNING

 进程正在被CPU执行,或者已经准备就绪,随时可以执行。当一个进程刚被创建时,就处于TASK_RUNNING状态。

2.TASK_INTERRUPTIBLE

 处于等待中的进程,待等待条件为真时被唤醒,也可以被信号或者中断唤醒。

3.TASK_UNINTERRUPTIBLE

 处于等待中的进程,待资源有效时唤醒,但不可以由其他进程通过信号或中断唤醒,这就导致无法通过kill信号来kill进程。

4.TASK_KILLABLE

  处于等待中的进程,待资源有效时唤醒,不可以由其他进程通过信号或中断唤醒(除了SIGKILL信号)。

5.TASK_TRACED

  正处于被调试状态的进程

6.TASK_DEAD

  进程退出时(调用do_exit),所处的状态

PCB(process control block)

在内核源码(sched.h)中用task_struct表示,其中包含(只列出重要部分)了

pid_t pid; //进程号

long state; //进程状态

int prio; //进程优先级

进程调度

调度策略:

SCHED_NORMAL(SCHED_OTHER):普通的分时进程

SCHED_FIFO:先入先出的实时进程

SCHED_RR:时间片轮转的实时进程

SCHED_BATCH:批处理进程

SCHED_IDLE:只在系统空闲时才能够被调度执行的进程

调度时机:

主动式:

在内核中直接调用schedule()。当进程需要等待资源等而暂时停止运行时,会将自己的状态挂起,并主动请求调度,让出CPU

被动式(抢占式调度):

1.用户态抢占 2.内核态抢占

用户态抢占发生在:

1.从系统调用返回用户空间

2.从中断处理程序返回用户空间

内核即将返回用户空间的时候,如果need_resched标志被设置,会导致schedule()被调用,即发生用户抢占。

1.当某个进程耗尽它的时间片时,会设置need_resched标志

2.当一个优先级更高的进程进入可执行状态的时候,也会设置need_resched标志。

缺点:进程/线程一旦运行到内核态,就可以一直执行下去,直到它主动放弃或者是时间片耗尽为止。这样会使得一些紧急的线程或进程长时间得不到运行,降低整个系统的实时性。

内核态抢占:

允许系统在内核态也支持抢占,更高优先级的进程/线程可以抢占正在内核态运行的低优先级进程/线程

发生在:

1.中断处理程序完成,返回内核空间之前

2.当内核代码进行解锁或者使能软中断的时候

不允许抢占的场合:

1.内核正在运行中断处理

2.进行软中断的时候(如进程时间片结束等)

3.进程正持有自旋锁、读写锁等。当持有这些锁时,不应该被抢占,否则由于抢占可能导致其他进程长期得不到锁,而让系统处于死锁状态。

4.内核正在执行调度程序Scheduler。因为执行调度程序本身就是为了进行新的调度,没有理由将调度程序抢占掉再运行调度程序。

抢占计数:

抢占式内核使用一个变量preempt_count,称为内核抢占计数,该变量被设置在thread_info结构中,每当内核进入上述不允许抢占的场合,变量preempt_count加1,表示内核不允许抢占,每当内核退出这几种状态,变量preempt_count就减1.

调度步骤:

Schedule函数工作流程:

1. 清理当前运行中的进程

2. 选择下一个要运行的进程

3. 设置新进程的运行环境

4. 进程上下文切换

Tips:

1.进程所使用的地址空间是独立编址的,是独立的用户空间,进程间的切换需要设置新的运行环境,效率较低

2.一个进程内的多个线程使用的地址都是进程中的地址,有共享的用户空间,所以线程的切换无需设置新的运行环境,只需要切换各自的栈就可以了,效率高。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录 1 进程的组织 5 1.1 进程相关数据结构 5 1.1.1 进程的基本信息 6 1.1.2 进程状态 10 1.1.3 TASK_RUNNING状态的进程链表 11 1.1.4 进程间关系 12 1.2 Linux的线程——轻量级进程 15 1.3 进程的创建——do_fork()函数详解 19 1.4 执行进程间切换 33 1.4.1 进程切换之前的工作 33 1.4.2 进程切换实务 —— switch_to宏 37 1.4.3 __switch_to函数 39 1.5 fork与vfock系统调用的区别 42 1.6 内核线程 46 1.7 挂起状态进程的组织 49 1.7.1 等待队列头 49 1.7.2 等待队列的操作 50 1.7.3 进程资源限制 55 1.8 系统调用execve() 56 1.8.1 拷贝用户态参数 57 1.8.2 重要的数据结构 61 1.8.3 search_binary_handler函数 66 1.8.4 目标文件的装载和投入运行 69 1.8.5 库函数 92 2 中断控制 94 2.1 中断的分类 94 2.2 中断的硬件环境 95 2.2.1 外部中断请求IRQ 95 2.2.2 中断描述符表 96 2.2.3 中断和异常的硬件处理 97 2.3 中断描述符表 99 2.3.1 中断门、陷阱门及系统门 99 2.3.2 IDT的初步初始化 100 2.4 异常处理 101 2.5 中断处理 106 2.5.1 中断向量 107 2.5.2 IRQ数据结构 108 2.5.3 do_IRQ()函数 113 2.5.4 中断服务例程 115 2.5.5 IRQ线的动态分配 116 2.6 下半部分 117 2.6.1 软中断 118 2.6.2 tasklet 121 2.6.3 工作队列 122 2.7定时器中断 124 2.7.1 时钟与定时器 124 2.7.2 定时器中断相关的数据结构 127 2.7.3 定时器中断的上半部分 129 3 进程调度 138 3.1 进程调度的概念 138 3.2 进程调度的数据结构和优先级 141 3.2.1 进程的优先级 141 3.2.2 数据结构 145 3.3 调度程序所使用的函数 151 3.3.1 scheduler_tick函数 151 3.3.2 try_to_wake_up函数 156 3.3.3 recalc_task_prio函数 160 3.4 schedule()函数 163 3.4.1 直接调用 163 3.4.2 延迟调用 164 3.4.3 进程切换之前所做的工作 168 3.4.4 完成进程切换时所执行的操作 171 3.4.5 进程切换后所执行的操作 173 3.5 多处理器运行队列的平衡 175 3.5.1 调度域 176 3.5.2 rebalance_tick()函数 178 3.5.3 load_balance()函数 180 3.5.4 move_tasks()函数 183 3.6 进程退出 187 3.6.1 进程终止 187 3.6.2 进程删除 189 4 进程的并发性体现 191 4.1 内核抢占 193 4.1.1 内核抢占概念 193 4.1.2 同步技术总揽 196 4.2 每CPU变量 197 4.3 原子操作 199 4.4 优化屏障和内存壁垒 203 4.4.1 优化屏障 204 4.4.2 内存壁垒 204 4.5 自旋锁 206 4.6 读写自旋锁 211 4.6.1 为读获取和释放一个锁 213 4.6.2 为写获取或释放一个锁 214 4.7 顺序锁 215 4.8 RCU机制 217 4.9 信号量 219 4.9.1 获取和释放信号量 221 4.9.2 读/写信号量 224 4.9.3 补充信号量 225 4.10 禁止本地中断 226 4.10.1 禁止本地中断 227 4.10.2 禁止下半部(可延迟函数) 229 4.11 一些避免竞争条件的实例 231 4.11.1 引用计数器 231 4.11.2 大内核锁 231 4.11.3 内存描述符读/写信号量 232 4.11.4 slab高速缓存链表的信号量 233 4.11.5 索引节点的信号量 233 4.12 内核同步与互斥的总结 233

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值