8进程的切换和系统的一般执行过程

王康 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

1,进程切换关键代码switch to分析

1,

因为有这些不同的进程,所以就需要不同的进程调度策略:

以下为系统调用来配置系统调用的优先级:

schedule函数负责实现调度,他是个内核函数且无法直接调用,只能间接调用。

时机就是中断处理过程(包括时钟中断、I/O中断、系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule();

2,

首先看schedule函数,然后进入_schedule:

pick next task就使用了某种进程调度策略;

之后完成进程上下文切换,通过context switch:

swtich to切换堆栈和寄存器状态

outter中因为在内核态,所以thread.sp为内核堆栈,thread.ip为当前进程eip;

input为下一个内核进程的堆栈和起点

整体为压栈当前进程堆栈,把esp保存在prev sp(这里用的字符串标记参数),之后把next sp放入esp,这两步完成了内核堆栈切换。

把1f放入prev ip,保存当前进程eip从这里恢复,然后push next ip,把next进程起点压入next堆栈,即栈底此时就是起点。

这里用的jmp  __switch to,通过寄存器a prev,d next传递参数。当函数结束return时,因为这里没有call来调用函数,所以会pop出$1f位置,从下图开始就认为是next开始执行:

从eip角度来看,从jmp就开始执行,从堆栈角度看save esp,restore esp之后便开始执行了,所以这里比较模糊:

为什么next进程由pop ebp呢?

因为next层级是prev进程

剩余代码:

1. 31#define switch_to(prev, next, last)                    \

2. 32do {                                 \

3. 33  /*                              \

4. 34   * Context-switching clobbers all registers, so we clobber  \

5. 35   * them explicitly, via unused output variables.     \

6. 36   * (EAX and EBP is not listed because EBP is saved/restored  \

7. 37   * explicitly for wchan access and EAX is the return value of   \

8. 38   * __switch_to())                     \

9. 39   */                                \

10. 40  unsigned long ebx, ecx, edx, esi, edi;                \

11. 41                                  \

12. 42  asm volatile("pushfl\n\t"      /* save    flags */   \

13. 43           "pushl %%ebp\n\t"        /* save    EBP   */ \

14. 44           "movl %%esp,%[prev_sp]\n\t"  /* save    ESP   */ \

15. 45           "movl %[next_sp],%%esp\n\t"  /* restore ESP   */ \

16. 46           "movl $1f,%[prev_ip]\n\t"    /* save    EIP   */ \

17. 47           "pushl %[next_ip]\n\t"   /* restore EIP   */    \

18. 48           __switch_canary                   \

19. 49           "jmp __switch_to\n"  /* regparm call  */ \

20. 50           "1:\t"                        \

21. 51           "popl %%ebp\n\t"     /* restore EBP   */    \

22. 52           "popfl\n"         /* restore flags */  \

23. 53                                  \

24. 54           /* output parameters */                \

25. 55           : [prev_sp] "=m" (prev->thread.sp),     \

26. 56             [prev_ip] "=m" (prev->thread.ip),        \

27. 57             "=a" (last),                 \

28. 58                                  \

29. 59             /* clobbered output registers: */     \

30. 60             "=b" (ebx), "=c" (ecx), "=d" (edx),      \

31. 61             "=S" (esi), "=D" (edi)             \

32. 62                                       \

33. 63             __switch_canary_oparam                \

34. 64                                  \

35. 65             /* input parameters: */                \

36. 66           : [next_sp]  "m" (next->thread.sp),        \

37. 67             [next_ip]  "m" (next->thread.ip),       \

38. 68                                       \

39. 69             /* regparm parameters for __switch_to(): */  \

40. 70             [prev]     "a" (prev),              \

41. 71             [next]     "d" (next)               \

42. 72                                  \

43. 73             __switch_canary_iparam                \

44. 74                                  \

45. 75           : /* reloaded segment registers */           \

46. 76          "memory");                  \

47. 77} while (0)

2,linux系统的一般执行过程

2,先压入用户进程X的内核堆栈,把当前进程内核堆栈相关信息ss esp 中断对应的服务历程起点加载到eip。

5,从schedule选出的进程Y(next必须曾经做过prev)

6,从Y 恢复现场

7,pop出Y发生中断时保存的eip esp flags

1,逻辑相同,只是内核线程无需切换状态

2,也不需要iret返回

3,fork时候,如果next是新创建的子进程,那么返回的执行起点是ret from fork,这里做switch to就比较复杂一点了,就不是从标号1的地方开始执行了

4,在execve内部修改了进程上下文

每个进程地址空间4G,3G以上只有内核态可以访问。进程发生切换它的内核态,如果每个进程都有自己空间如何切换呢?其实内核进程都是共享的,只是其他的进程描述符和上下文切换。只有返回到用户态才会有不同。

那个进程招手都可以陷入内核态,走一程之后返回到用户态。

3,linux操作系统架构概览

敲击键盘Io中断,把当前进程中断,在控制台输出也是中断;

COW写时复制技术;

0到3G的部分,进程地址空间;

如果main函数有个gets(),gets是个系统调用就会陷入内核,从用户态堆栈进入内核。压栈等等。

然后进入进程管理,等待键盘输入过程,cpu会调度到其他进程执行,由进程管理调度。在执行其他进程过程中也在等待着键盘的输入,输入键盘就发生IO中断,调度回来。

敲击之后发生IO中断给CPU,cpu就执行中断处理程序,过程中知道键盘的输入,且是X进程在等待输入,从阻塞态变为就绪态。

最后从系统调用返回。

4,实验:

远程调试并设置断点

调试运行

5,总结

进程调度程序是内核重要的组成部分,因为运行着的进程首先在使用计算机(至少在我们大多数人看来)。然而,满足进程调度的各种需要绝不是轻而易举的,很难找到“一刀切”的算棒,既适合众多的可运行进程,又具有可伸缩性,还能在调度周期和吞吐量之间求得平衡,同时还满足各种负载的需求。不过, Linux 内核的新CFS 调度程序尽量满足了各个方面的需求,并以较完善的可伸缩性和新颖的方挫提供了最佳的解决方案。前面的章节覆盖了进程管理的相关内容,本章则考察了进程调度所遵循的基本原理、具体实现、调度算能以及目前Linux 内核所使用的接口。

时间: 2024-08-11 05:44:02

8进程的切换和系统的一般执行过程的相关文章

Linux内核设计第八周 ——进程的切换和系统的一般执行过程

Linux内核设计第八周 ——进程的切换和系统的一般执行过程 第一部分 知识点总结

第八节 进程的切换和系统的一般执行过程

第八周 进程的切换和系统的一般执行过程 By 135217孙小博 本周的主要内容: Linux中进程调度的基本概念与相关知识 schedule函数如何实现进程调度 Linux进程的执行过程(一般情况与特殊情况) 宏观描述Linux系统执行 进程切换的主要代码switch_to 进程的调度时机与进程的切换 不同类型进程的不同调度需求 第一种分类: I/O-bound:频繁进行I/O,并且需要花费很多时间等待I/O完成 CPU-bound:计算密集,需要大量的CPU时间进行运算 第二种分类: 批处理

《Linux内核分析》第八周学习小结 进程的切换和系统的一般执行过程

进程的切换和系统的一般执行过程 一.进程调度的三个时机: 1.中断处理过程(包括时钟中断.I/O中断.系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule(): 2.内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度: 3.用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度. 二.swi

实验八 进程的切换和系统的一般执行过程

实验八 进程的切换和系统的一般执行过程 20135114王朝宪 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.进程切换的关键代码switch_to分析 1.1 进程调度与进程调度的时机分析 操作系统原理中介绍了大量进程调度算法,这些算法从实现的角度看仅仅是从运行队列中选择一个新进程,选择的过程中运用了不同的策略而已. 对于理解操作系统的工作机制,反而是进程的调度时机与进程的切换机制

LINUX内核分析第八周学习总结——进程的切换和系统的一般执行过程

LINUX内核分析第八周学习总结——进程的切换和系统的一般执行过程 黄韧(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.知识概要 Linux中进程调度的基本概念与相关知识 schedule函数如何实现进程调度 Linux进程的执行过程(一般情况与特殊情况) 宏观描述Linux系统执行 二.学习笔记 (一)进程切换的关键代码switch_to分析 进程进度与进程调度的时机分析 1.

《Linux内核》第七周 进程的切换和系统的一般执行过程 20135311傅冬菁

进程的切换和系统的一般执行过程 一.内容总结与分析 进程调度与进程调度时机 进程调度需求的分类: 第一种分类方式: I/O -bound(频繁进行I/O,通常会花很多时间等待I/O操作) CPU-bound(计算密集型.需要花大量CPU时间进行运算) 第二种分类方式: 批处理进程(后台进行,典型:编译程序.科学计算) 实时进程(有实时需求响应时间短.稳,典型:视频.音频.机械控制) 交互式进程(与用户交互多,响应时间要快,典型:shell.文本编辑程序.图形应用程序) Linux调度基于分时和优

Linux内核分析——进程的切换和系统的一般执行过程

进程的切换和系统的一般执行过程 一.进程切换的关键代码switch_to分析 (一)进程调度与进程调度的时机分析 1.不同类型的进程有不同的调度需求 第一种分类: (1)I/O-bound:频繁进行I/O,花费很多时间等待I/O操作的完成. (2)CPU-bound:计算密集型,需要大量CPU时间进行计算. 第二种分类: (1)批处理进程:不必交互.很快响应. (2)实时进程:要求响应时间短. (3)交互式进程(shell). 2.调度策略:是一组规则,它们决定什么时候以怎样的方式选择一个新进程

20135239 益西拉姆 linux内核分析 进程的切换和系统的一般执行过程

week 8 进程的切换和系统的一般执行过程 [ 20135239 原文请转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] 一.进程调度与进程调度的时机分析 操作系统原理中介绍了大量进程调度算法,这些算法从实现的角度看仅仅是从运行队列中选择一个新进程,选择的过程中运用了不同的策略而已.对于理解操作系统的工作机制,反而是进程的调度时机与进程的切换机制更为关键. 不同类型的进程有不同的调度需求 第一

第八周:进程的切换和系统的一般执行过程

吕松鸿 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.进程切换的关键代码switch_to分析 1.进程调度与进程调度的时机分析 不同类型的进程有不同的调度需求 第一种分类: I/O-bound:频繁进行I/O,花费很长时间等待I/O CPU-bound:计算密集型,需要大量CPU时间进行计算 第二种分类: 批处理进程:不必交互.很快响应 实时进程:要求响应时间短 交互式进

《Linux内核分析》 第八节 进程的切换和系统的一般执行过程

一.进程切换的关键代码switch_to分析 1.进程进度与进程调度的时机分析 中断处理过程(包括时钟中断.I/O中断.系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule(): 内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类的特殊的进程可以主动调度,也可以被动调度: 用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度.