想知道内核什么时候给进程重新分配时间片,最好的办法就是阅读源代码(其中已经打了注释)

/****************************************************************************/
/* 功能:进程调度。															*/
/*		 先对alarm和信号进行处理,如果某个进程处于可中断睡眠状态,并且收	*/
/*		 到信号,则把进程状态改成可运行。之后在处可运行状态的进程中挑选一个	*/
/*		 并用switch_to()切换到那个进程										*/
/* 参数:(无)																*/
/* 返回:(无)																*/
/****************************************************************************/
void schedule(void)
{
	int i,next,c;
	struct task_struct ** p;
/* check alarm, wake up any interruptible tasks that have got a signal */
// 首先处理alarm信号,唤醒所有收到信号的可中断睡眠进程
	for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
		if (*p) {
			// 如果进程设置了alarm,并且alarm已经到时间了
			if ((*p)->alarm && (*p)->alarm < jiffies) {
					// 向该进程发送SIGALRM信号
					(*p)->signal |= (1<<(SIGALRM-1));
					(*p)->alarm = 0;	// 清除alarm
				}
//可屏蔽信号位图BLOCKABLE定义在sched.c第24行,(~(_S(SIGKILL) | _S(SIGSTOP)))
// 说明SIGKILL和SIGSTOP是不能被屏蔽的。
// 可屏蔽信号位图 & 当前进程屏蔽的信号位图 = 当前进程实际屏蔽的信号位图
// 当前进程收到的信号位图 & ~当前进程实际屏蔽的信号位图
//							= 当前进程收到的允许相应的信号位图
// 如果当前进程收到允许相应的信号,并且当前进程处于可中断睡眠态
// 则把状态改成运行态,参与下面的选择过程
			if (((*p)->signal & ~(_BLOCKABLE & (*p)->blocked)) &&
			(*p)->state==TASK_INTERRUPTIBLE)
				(*p)->state=TASK_RUNNING;
		}
/* this is the scheduler proper: */
// 下面是进程调度的主要部分
	while (1) {
		c = -1;
		next = 0;
		i = NR_TASKS;
		p = &task[NR_TASKS];
		while (--i) {		// 遍历整个task[]数组
			if (!*--p)		// 跳过task[]中的空项
				continue;
			// 寻找剩余时间片最长的可运行进程,
//  c记录目前找到的最长时间片
// next记录目前最长时间片进程的任务号
			if ((*p)->state == TASK_RUNNING && (*p)->counter > c)
				c = (*p)->counter, next = i;
		}
	// 如果有进程时间片没有用完c一定大于0。这时退出循环,执行 switch_to任务切换
		if (c) break;
	// 到这里说明所有可运行进程的时间片都用完了,则利用任务优先级重新分配时间片。
	// 这里需要重新设置所有任务的时间片,而不光是可运行任务的时间片。
	// 利用公式:counter = counter/2 + priority
		for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
			if (*p)
				(*p)->counter = ((*p)->counter >> 1) +
						(*p)->priority;
	// 整个设置时间片过程结束后,重新进入进程选择过程
	}
	// 当的上面的循环退出时,说明找到了可以切换的任务
	switch_to(next);
}

注意到,当系统中现在没有可以投入运行的进程,但是存在就绪态,不过其时间片为0,此时,就需要重新为进程分配时间片。

注意:

分配时间片不是对某一个进程而言的,是对系统中所有的进程而言,除进程0外。

Linux0.11进程分配时间片的策略的更多相关文章

  1. Linux0.11进程切换和TSS结构

    TSS 全称为task state segment,是指在操作系统进程管理的过程中,进程切换时的任务现场信息.       X86体系从硬件上支持任务间的切换.为此目的,它增设了一个新段:任务状态段( ...

  2. linux0.11改进之四 基于内核栈的进程切换

    这是学习哈工大李治军在mooc课操作系统时做的实验记录.原实验报告在实验楼上.现转移到这里.备以后整理之用. 完整的实验代码见:实验楼代码 一.tss方式的进程切换 Linux0.11中默认使用的是硬 ...

  3. 对Linux0.11 中 进程0 和 进程1分析

    1. 背景 进程的创建过程无疑是最重要的操作系统处理过程之一,很多书和教材上说的最多的还是一些原理的部分,忽略了很多细节.比如,子进程复制父进程所拥有的资源,或者子进程和父进程共享相同的物理页面,拥有 ...

  4. Linux0.11内核源码——内核态线程(进程)切换的实现

    以fork()函数为例,分析内核态进程切换的实现 首先在用户态的某个进程中执行了fork()函数 fork引发中断,切入内核,内核栈绑定用户栈 首先分析五段论中的第一段: 中断入口:先把相关寄存器压栈 ...

  5. linux0.11内核源码——进程各状态切换的跟踪

    准备工作 1.进程的状态有五种:新建(N),就绪或等待(J),睡眠或阻塞(W),运行(R),退出(E),其实还有个僵尸进程,这里先忽略 2.编写一个样本程序process.c,里面实现了一个函数 /* ...

  6. Linux0.11之进程0创建进程1(1)

    进程0是由linus写在操作系统文件中的,是预先写死了的.那么进程0以后的进程是如何创建的呢?本篇文章主要讲述进程0创建进程1的过程. 在创建之前,操作系统先是进行了一系列的初始化,分别为设备号.块号 ...

  7. Linux0.11小结

    第一部分 基础内容 1.操作系统基础     操作系统是计算机硬件系统与用户程序间重要环节,理解操作系统的原理是编写优秀代码的基础.教课书中阐述的操作系统一般由5部分组成. 一个最简单的操作系统,可以 ...

  8. Linux0.11内核剖析--内核体系结构

    一个完整可用的操作系统主要由 4 部分组成:硬件.操作系统内核.操作系统服务和用户应用程序,如下图所示: 用户应用程序是指那些字处理程序. Internet 浏览器程序或用户自行编制的各种应用程序: ...

  9. linux0.11下的中断机制分析

    http://orbt.blog.163.com/     异常就是控制流中的突变,用来响应处理器状态中的某些变化.当处理器检测到有事件发生时,它就会通过一张叫做异常表的跳转表,进行一个间接过程调用, ...

随机推荐

  1. rw 模板设置

    在编译的时候只有写出rw之后使用alt+/就可以将模板代码全部展现出来. rw读写模板代码: InputStream in = null; OutputStream out = null; try { ...

  2. 将Python当作计算器

    在交互模式中,最近一个表达式的值赋给变量 _.这样我们就可以把它当作一个桌面计算器,很方便的用于连续计算.例如: >>> price = 1.25 #声明变量price >&g ...

  3. ubuntu初始化python3+postgresql+uwsgi+nginx+django

    一. postgresql 数据库 安装 apt-get update apt-get install postgresql 进入psql客户端 sudo -u postgres psql 创建数据库 ...

  4. 好IT男不能“淫”-谈IT人员目前普遍存在的“A情绪”

    <如果当道德无法约束你的时候...那么就让对疾病的恐惧来制约你吧> 前言 在写这篇文章前我的心情无比的沉重.几次提笔欲写,几次又未能完成,可是最终让我"奋笔疾书"的原因 ...

  5. 【安卓开发】Android为什么选择binder

    Binder (Android技术内幕): 在上面这些可供选择的方式中,Android使用得最多也最被认可的还是Binder机制. 为什么会选择Binder来作为进程之间的通信机制呢?因为Binder ...

  6. Redis中的关系查询

    本文对Redis如何保存关系型数据,以及如何对其匹配.范围.模糊查询进行举例讲解,其中模糊查询功能基于最新的2.8.9以后版本. 1 关系型数据的存储 以Staff对象为例,在关系型数据库或类似Gri ...

  7. static 变量(静态变量)

    在C++的面向对象编程中,static还可以加在类的数据成员或成员函数之前.这样定义的数据成员或成员函数就被类所拥有,而不再属于类的对象. #include <iostream> usin ...

  8. activiti 数据库升级 upgrade

    分享牛原创(尊重原创 转载对的时候第一行请注明,转载出处来自分享牛http://blog.csdn.net/qq_30739519) 在项目中我们如果使用activiti 工作流引擎的时候,肯定是需要 ...

  9. actionbar详解(二)

    经过前面两篇文章的学习,我想大家对ActionBar都已经有一个相对较为深刻的理解了.唯一欠缺的是,前面我们都只是学习了理论知识而已,虽然知识点已经掌握了,但是真正投入到项目实战当中时会不会掉链子还很 ...

  10. xlsx批量转为utf8的csv

    xlsx批量转为utf8的csv(金庆的专栏)策划的配置表为 xlsx 表格,可以有注释,公式.服务器和客户端使用的配置文件需要转成 csv 文件.使用 WPS 另存无法批量转换,并且结果不是utf8 ...