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

本文探讨了Linux内核中进程调度的时机与实现细节,通过分析schedule()函数的调用情况,总结了进程调度的主要场景,并深入研究了系统调用后的进程切换流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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


貌似是最后一周课了,竟然坚持下来了!!!!


1、在内核代码中搜索schedule()函数,看都是哪里调用了schedule(),判断我们课程内容中的总结是否准确;


一搜吓了一大跳,

Searched full:schedule (Results 1 - 25 of 1213) sorted by relevance

看来直接挨个看是不太实际了,这里我重点挑出了之前的课程内容中出现的schedule


想了想发现这实际上就是探究linux进程调度的时机

Linux进程调度时机主要有

1、进程状态转换的时刻:进程终止、进程睡眠;

2、当前进程的时间片用完时(current->counter=0);

3、设备驱动程序

4、进程从中断、异常及系统调用返回到用户态时;



时机1,进程要调用sleep()或exit()等函数进行状态转换,这些函数会主动调用调度程序进行进程调度;


时机2,由于进程的时间片是由时钟中断来更新的,因此,这种情况和时机4是一样的。


时机3,当设备驱动程序执行长而重复的任务时,直接调用调度程序。在每次反复循环中,驱动程序都检查need_resched的值,如果必要,则调用调度程序schedule()主动放弃CPU。


时机4,在system_call的结尾调用

596work_resched:
597	call schedule
598	LOCKDEP_SYS_EXIT

2、使用gdb跟踪分析一个schedule()函数

在系统调用结束后

确实调用了schedule,在跟踪时无法直接追踪汇编函数switch_to,因此还是直接分析代码吧

#define switch_to(prev, next, last)					\
32do {									\
33	/*								\
34	 * Context-switching clobbers all registers, so we clobber	\
35	 * them explicitly, via unused output variables.		\
36	 * (EAX and EBP is not listed because EBP is saved/restored	\
37	 * explicitly for wchan access and EAX is the return value of	\
38	 * __switch_to())						\
39	 */								\
40	unsigned long ebx, ecx, edx, esi, edi;				\
41									\
42	asm volatile("pushfl\n\t"		/* save    flags */	\
43		     "pushl %%ebp\n\t"		/* save    EBP   */	\
44		     "movl %%esp,%[prev_sp]\n\t"	/* save    ESP   */ \
45		     "movl %[next_sp],%%esp\n\t"	/* restore ESP   */ \
46		     "movl $1f,%[prev_ip]\n\t"	/* save    EIP   */	\
47		     "pushl %[next_ip]\n\t"	/* restore EIP   */	\
48		     __switch_canary					\
49		     "jmp __switch_to\n"	/* regparm call  */	\
50		     "1:\t"						\
51		     "popl %%ebp\n\t"		/* restore EBP   */	\
52		     "popfl\n"			/* restore flags */	\
53									\
54		     /* output parameters */				\
55		     : [prev_sp] "=m" (prev->thread.sp),		\
56		       [prev_ip] "=m" (prev->thread.ip),		\
57		       "=a" (last),					\
58									\
59		       /* clobbered output registers: */		\
60		       "=b" (ebx), "=c" (ecx), "=d" (edx),		\
61		       "=S" (esi), "=D" (edi)				\
62		       							\
63		       __switch_canary_oparam				\
64									\
65		       /* input parameters: */				\
66		     : [next_sp]  "m" (next->thread.sp),		\
67		       [next_ip]  "m" (next->thread.ip),		\
68		       							\
69		       /* regparm parameters for __switch_to(): */	\
70		       [prev]     "a" (prev),				\
71		       [next]     "d" (next)				\
72									\
73		       __switch_canary_iparam				\
74									\
75		     : /* reloaded segment registers */			\
76			"memory");					\
77} while (0)

这一过程非常 像一个超简单的系统内核 中的切换过程

1、新进程执行过,对于执行过的进程,只要保存好现在的现场(ebp存入堆栈中,esp(指向刚刚存进去的ebp)放入之前的thread结构体的sp中,eip放入thread结构体的ip中),恢复刚才的现场,也就是将新进程的eip,esp,ebp放出来。esp是直接从sp中赋给esp,eip从ip放入栈再通过ret弹出来(因为eip不能被直接修改),此时esp是指向刚才的ebp的(想不明白可以看esp存到sp里时指的是谁?)。但是弹出ebp这个过程要在ret之后,因为那个eip存的时候是指的1:,新的进程自然就会在它的1:处恢复

总结:学习完这门课 对堆栈 进程 有了很深刻的认识,也解决了ucos学习中不理解的很多问题。

通过优先权法和轮转算法的模拟加深对进程概念和进程调度过程理解,掌握进程状态之间的切换,同时掌握进程调度算法的实现方法和技巧。 要求: 1.用C语言或C++语言来实现对n个进程采用优先权优先算法以及轮转算法的进程调度。 2.每个用来标识进程进程控制块PCB用结构来描述,包括以下字段: (1)进程优先数ID,其中0为闲逛进程,用户进程的标识数为1,2,3…。 (2)进程优先级Priority,闲逛进程(idle)的优先级为0,用户进程的优先级大于0,且随机产生,优先数越大,优先级越高。 (3)进程占用的CPU时间CPUtime,进程每运行一次,累计值等于4。 (4)进程总共需要运行时间Alltime,利用随机函数产生。 (5)进程状态,0:就绪态;1:运行态;2:阻塞态。 (6)队列指针next,用来将多个进程控制块PCB链接为队列。 3.优先数改变的原则 (1)进程在就绪队列中每呆一个时间片,优先数增加1。 (2)进程每运行一个时间片,优先数减3。 4.在调度前,系统中拥有的进程数PCB_number由键盘输入,经初始化后,所有的进程控制块PCB链接成就绪队列。其中它们的初始化状态如下: This is an example for priority processing : Input the number of the PCB to be started :1 PCB: ID priority CPUtime ALLtime State 5 86 4 64 ready 1 32 20 68 ready 6 59 0 47 ready 2 18 20 62 ready 4 86 4 6 ready 7 72 4 51 ready 8 76 0 60 ready 9 4 4 19 ready 13 94 12 19 ready 16 88 12 24 ready 5.为了清楚地观察诸进程调度过程,程序应将每个时间片内的进程的情况显示出来,参照输出格式如下所示: This is an example for priority processing : Input the number of the PCB to be started : PCB: ID priority CPUtime ALLtime State 1 42 0 68 ready 建立: Creating -> ready 1 41 4 68 running 变迁1:ready -> running 1 41 0 68 blocked 变迁2:running -> blocked 1 41 0 68 ready 变迁4:running -> ready The idle prcess is running! 变迁1:ready -> running The idle prcess is completed! 销毁: running -> Destroy The idle prcess is running! 变迁1:ready -> running The idle prcess is completed! 销毁: running -> Destroy The idle prcess is running! 变迁1:ready -> running
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值