当前位置: 首页 > news >正文

进程调度模块

目录

1.进程介绍


2.进程调度

2.1.进程状态

2.2.进程调度函数 ---schedule

2.3.进程切换函数 ---switch_to()


1.进程介绍

在进程模块里面,我们知道了进程就是一个task_struct的结构体,里面含有进程的各种信息。进程存放在进程数组task_struct的数组里面。

2.进程调度

在进程调度里面主要的两个函数:

//进程调度函数

        void schedule(void);

//切换到下一个进程 这个功能使用宏定义完成的
       switch_to(next);

2.1.进程状态

运行态: 可以被运行

就绪态: 进程切换时,只能在就绪态里面挑选进程

可中断睡眠状态: 可以被信号打断,变成就绪态或者运行态

不可中断睡眠状态: 只能被wakeup所唤醒变成就绪态或者运行态

暂停状态: 收到SIGTOP,SIGTSTP,SIGTTIN

僵死状态: 进程停止运行,但是父进程没有回收,  waitpid函数。

2.2.进程调度函数 ---schedule

1. 检查所有进程的定时器,然后唤醒某一些进程,将进程从可中断睡眠状态变为就绪态

2.循环task列表 根据counter大小决定进程切换

       (1)如果找到最大值,而且不为0,直接返回,没有(2)了。

        (2)如果都为0,进行时间片的重新分配,然后重新执行2步骤。

3.切换到下一个进程------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 */

	for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
		if (*p) {//alarm是用来设置警告,比如jiffies有1000个可能其中一些需要警告那么就用alarm来实现
			if ((*p)->alarm && (*p)->alarm < jiffies) {
					(*p)->signal |= (1<<(SIGALRM-1));
					(*p)->alarm = 0;
				}
				//~(_BLOCKABLE & (*p)->blocked  
				//&&(*p)->state==TASK_INTERRUPTIBLE
				//用来排除非阻塞信号
				//如果该进程为可中断睡眠状态 则如果该进程有非屏蔽信号出现就将该进程的状态设置为running
			if (((*p)->signal & ~(_BLOCKABLE & (*p)->blocked)) &&
			(*p)->state==TASK_INTERRUPTIBLE)
				(*p)->state=TASK_RUNNING;
		}

/* this is the scheduler proper: */
	// 以下思路,循环task列表 根据counter大小决定进程切换
	while (1) {
		c = -1;
		next = 0;
		i = NR_TASKS;
		p = &task[NR_TASKS];
		while (--i) {
			if (!*--p)
				continue;//进程为空就继续循环
			if ((*p)->state == TASK_RUNNING && (*p)->counter > c)//找出c最大的task
				c = (*p)->counter, next = i;
		}
		if (c) break;//如果c找到了,就终结循环,说明找到了
		//进行时间片的重新分配
		for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
			if (*p)//这里很关键,在低版本内核中,是进行优先级时间片轮转分配,这里搞清楚了优先级和时间片的关系
			//counter = counter/2 + priority
				(*p)->counter = ((*p)->counter >> 1) +
						(*p)->priority;
	}
	//切换到下一个进程 这个功能使用宏定义完成的
	switch_to(next);
}

  2.3.进程切换函数 ---switch_to()

 1.先判断是否为当前进程,如果是,不用切换

2.切换进程:

        (1)将进程赋值给全局变量current这个变量,就可以完成进程切换

        (2)将进程的上下文(TSS和当前堆栈中的信息)切换

// 进程切换是用汇编宏定义实现的
//1. 将需要切换的进程赋值给当前进程的指针
//2. 将进程的上下文(TSS和当前堆栈中的信息)切换
#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])); \
}

 3.sleep_on函数

当某个进程想访问CPU资源,但是CPU资源被占用访问不到,就会休眠。休眠是以链表形成的,类似递归的情况。-----sleep等待队列

 

// 当某个进程想访问CPU资源,但是CPU资源被占用访问不到,就会休眠
void sleep_on(struct task_struct **p)
{
	struct task_struct *tmp;

	if (!p)//如果传进来的是空的 就返回
		return;
	if (current == &(init_task.task))//当前进程是0号 
		panic("task[0] trying to sleep");//就打印并且返回
	tmp = *p;
	*p = current;//这两步相当于 给休眠链表添加了一个新node
	// 其实核心就是把state置为TASK_UNINTERRUPTIBLE
	current->state = TASK_UNINTERRUPTIBLE;
	schedule();
	if (tmp)
		tmp->state=0;
}

相关文章:

  • 烟台做网站建设电话/举例说明seo
  • 团购网站怎么推广/变现流量推广app
  • 简述网站开发工作流程/微信小程序开发费用
  • 网站建设实习目的/揭阳市seo上词外包
  • 广汉手机网站设计/关键词优化怎么操作
  • 提供网站建设服务的网站价格/aso应用商店优化原因
  • 【ROS】使用pluginlib自定义costmap地图层
  • npm的使用及镜像配置
  • [oeasy]python0051_ 转义_escape_字符_character_单引号_双引号_反引号_ 退格键
  • 技术分享 | OceanBase 4.X 最小化单机部署
  • 【问题解决】Tomcat启动服务时提示Filter初始化或销毁出现java.lang.AbstractMethodError错误
  • 磨金石教育影视技能干货分享|浅析中国CG特效的发展现状
  • 【项目实战】使用Java Keytool工具生成的CSR给第三方云平台签名
  • OpenCV(11)-图像的分割与修复
  • CSS造成阻塞的原理
  • Unidbg模拟执行某段子so实操教程(二) LoadSo对比
  • Vue CLI
  • 上海亚商投顾:沪指重返3200点 牛市旗手回归!