Linux0.11调度程序,Linux 0.11版 进程调度文本解说

0.11核中进程的调度主要由四个部分数组成:调度初始化、调度、睡眠、唤醒。

一、调度初始化:sched_init()

我们知道在内核初始化(main)过程中,要将任务0转换到用户态下执行,也就是建立Linux中的第一个用户程序。既然任务0之前是在内核态下执行的,所以用的是系统的ldt、和tss,要在用户态下执行,就要使用用户态下的ldt、tss,那么,调度初始化的其中一个任务就是建立任务0的ldt和gdt。下面说一下sched_init()的具体工作过程:

1)在gdt中设置ldt、gdt:ldt和gdt的定义在sched.h中。

2)将eflags中的NT置位:记得在前面关于任务切换的说明中,我提到在main的中sched_init()之后,要调用move_to_user_mode()实现核心态到用户态的转换,而在move_to_user_mode()中,最后调用了iret,如果将NT为0,就不会引起进程的切换了。

3)加载tss和ldt:手动加载仅这一次,以后都是通过任务的切换CPU自动加载的。在这里,因为是第一个用户任务,所以需要手动设置。

4)初始化8253定时器。

5)在IDT中设置时钟的中断门和系统调用的中断门。

二、调度:schedule()

这个函数的主要工作就是从所有处在就绪状态的进程中选择下一个要运行的进程。具体工作过程是这样的:它首先检查在处在可中断睡眠状态下的进程是否除了阻塞信号以外别的信号,如果存在,则将它置成就绪状态。然后循环检查任务数组中的所有处在就绪状态的任务,挑选出剩余执行时间值最大的一个任务,利用switch_to()函数切换到该任务。如果发现所有就绪进程的时间片都是0,则根据任务的优先级,重新计算每个任务的时间片,在重新执行循环检查所有就绪任务的执行剩余时间。

其中,这个函数的核心之一就是switch_to()函数,它能实现任务的切换,它的定义在sched.h中,主要原理就是利用如果ljmp的操作数是任务门描述符就会引起任务的切换。

三、睡眠sleep_on()、interruptible_sleep_on()

在接收这个函数的工作原理之前,先了解一个数据结构:等待队列。等待队列其

其实就是一个进程指针链表,所有由于等待同一个资源的睡眠进程组成一个等待队列。这个链表的连接并不是通常意义上的通过next连接,而是通过tmp,每个睡眠进程都有一个tmp指针,它指向这个进程之前睡眠的那个进程,这样就将等待同一个资源的睡眠进程连接起来了。每个进程睡眠的时候,就将自己插入到这个链表的第一个,这样后睡眠的进程排在前面;被唤醒的时候,还要把它后面的进程,也就是在它之前睡眠的进程也要唤醒,目的是在自己使用完这资源之后,可以让之前的进程使用该资源,这个进程再唤醒它之前的进程……,这样逐个唤醒这个等待队列中的所有进程。简言之,当自己需要的资源不在的时候,就一个个进入等待队列,当资源回来的时候,再一个个唤醒使用这个资源。

睡眠函数的主要功能就是当一个进程所请求的资源正忙或者不再内存是,就将该进程放到等待队列等待一段时间。当进程切换回来后又继续接着运行。这里有两个函数:sleep_on()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值