08 linux011进程调度

Posted 资质平庸的程序员

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了08 linux011进程调度相关的知识,希望对你有一定的参考价值。

1 linux 0.11 用户进程调度时机

[1] 主动请求调度(如调用 pause );

[2] 进入系统调用时内核资源不够,则主动睡眠当前进程并调度其他进程运行,当内核资源可用时被唤醒,从而再次进入能被调度的状态;

[3] 在定时器中断中,当前进程时间片运行完毕时;

[4] 系统调用结束时检查当前进程已进入不可运行状态。

2 调度策略

[1] 遍历管理进程的所有数据结构体, 检查各进程所设置的报警是否超时, 若超时则为当前进程设置报警超时信号。若当前进程有可被处理的信号且处于可被唤醒状态则置该进程为可调度状态, 让其加入可被调度进程的行列中。

[2] 遍历处于可被调度状态的进程,从当前进程切换到时间片最大的进程。若当前除超级进程外无其他可被调度的进程保持超级进程的运行。若除超级进程外的其余可被调度进程的时间片皆为0,则用进程的优先级重新设置进程的时间片,然后切换到首次遍历到的时间片为0的进程运行。

3 切换过程 switch_to

/* switch_to,
 * 切换到任务号为n的进程中运行。
 *
 * 内联汇编输入部分。
 * "d" (_TSS(n)), edx = _TSS(n)即欲切换进程的TSS选择符;
 * "c" ((long) task[n])),ecx = (long) task[n]即管理欲切换进程的结构体地址;
 * "m" (*&__tmp.a), 内存变量__tmp.a;
 * "m" (*&__tmp.b), 内存变量__tmp.b。
 *
 * 内联汇编指令部分。
 * cmpl %%ecx,_current; je 1f
 * 比较欲切换进程是否为当前运行进程,若是则向前跳转到标号1处结束进程切换;
 * 
 * movw %%dx,%1; xchgl %%ecx,_current
 * 若欲切换进程非当前进程,则将dx(TSS选择符)赋给%1即__tmp.b,然后将当前进
 * 程结构体指针current指向欲切换进程结构体;
 *
 * ljmp %0
 * 随后通过长跳转指令ljmp实现任务切换,此处的ljmp指令将__tmp所在内存段内容
 * 作为操作数——低4字节为偏移地址, 接下来的2字节(__tmp.b低2字节)为段选择符。
 * 由于此处的段选择符将索引到描述TSS的GDT表项,这将会引起任务切换。这个过程
 * 大体如下:将本进程运行上下文备份到其TSS中; 将欲切换进程TSS选择符加载到TR
 * 寄存器中并从该TSS种获取欲切换进程运行上下文(CS:EIP SS:ESP LDT选择符等)。
 * (所以没在__tmp.a中指定偏移地址是没有关系的)。
 *
 * cmpl %%ecx,_last_task_used_math; jne 1f; clts
 * 这条语句在本进程再次本调度时执行,该语句检查上次是否使用过协处理器。
 * 若没有则向前跳转标号1处,若使用过则清协处理器使用标志(CR0 TS位)。*/
#define switch_to(n) \\
struct long a,b; __tmp; \\
__asm__("cmpl %%ecx,_current\\n\\t" \\
    "je 1f\\n\\t" \\
    "movw %%dx,%1\\n\\t" \\
    "xchgl %%ecx,_current\\n\\t" \\
    "ljmp %0\\n\\t" \\
    "cmpl %%ecx,_last_task_used_math\\n\\t" \\
    "jne 1f\\n\\t" \\
    "clts\\n" \\
    "1:" \\
    ::"m" (*&__tmp.a),"m" (*&__tmp.b), \\
    "d" (_TSS(n)),"c" ((long) task[n])); \\

进程切换过程可见10 子进程创建和多进程调度开销分析中的进程调度主要过程 CPU自动完成部分

以上是关于08 linux011进程调度的主要内容,如果未能解决你的问题,请参考以下文章

10 linux011子进程创建和多进程调度开销分析

10 linux011子进程创建和多进程调度开销分析

理解进程调度时机跟踪分析进程调度与进程切换的过程(Linux)

linux内核—进程调度时机

Linux系统编程Linux进程调度

进程管理-第二节23:进程调度的时机切换与过程方式调度器和闲逛进程