linux 0.11 任务调度schedule
来源:互联网 发布:php程序源码 编辑:程序博客网 时间:2024/05/17 22:17
Linux0.11 任务调度schedule
函数定义在sched.c当中,如下:
void schedule(void){ int i,next,c; struct task_struct ** p; /* check alarm, wake up any interruptible tasks that havegot a signal */ for(p= &LAST_TASK ; p> &FIRST_TASK ; --p) if (*p) { if ((*p)->alarm &&(*p)->alarm< jiffies) { (*p)->signal|= (1<<(SIGALRM-1)); (*p)->alarm =0; } 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) { if (!*--p) continue; if ((*p)->state ==TASK_RUNNING && (*p)->counter> c) c = (*p)->counter, next =i; } if (c) break; for(p = &LAST_TASK; p > &FIRST_TASK; --p) if (*p) (*p)->counter= ((*p)->counter>> 1) + (*p)->priority; } switch_to(next);}
在linux0.11中,最多有64个任务同时存在,任务的相关信息存放一个数组里面,数组的结构(sched.h)如下:
struct task_struct {/* these are hardcoded - don't touch */ long state; /* -1 unrunnable, 0 runnable, >0 stopped */ long counter; long priority; long signal; struct sigaction sigaction[32]; long blocked; /* bitmap of masked signals *//* various fields */ int exit_code; unsigned long start_code,end_code,end_data,brk,start_stack; long pid,father,pgrp,session,leader; unsigned short uid,euid,suid; unsigned short gid,egid,sgid; long alarm; long utime,stime,cutime,cstime,start_time; unsigned short used_math;/* file system info */ int tty; /* -1if no tty, so it must be signed */ unsigned short umask; struct m_inode * pwd; struct m_inode * root; struct m_inode * executable; unsigned long close_on_exec; struct file * filp[NR_OPEN];/* ldt for this task 0 - zero 1 - cs 2 - ds&ss */ struct desc_struct ldt[3];/* tss for this task */ struct tss_struct tss;};
在任务调度中,需要注意4个参数:state和signal,blocked,alarm。State是任务的状态,有5中,在sched.h当中定义:
#define TASK_RUNNING 0//就绪,可运行状态,个人理解为正在运行或者等待运行的任务
#define TASK_INTERRUPTIBLE1 //可中断睡眠状态可有信号,wake_up唤醒,从sys_pause,sys_waitpid,interruptiable_sleep_on进入
#define TASK_UNINTERRUPTIBLE 2 //不可中断睡眠,只能由sleep_on()进入,wake_up函数唤醒
#define TASK_ZOMBIE 3 //僵死状态,不能再被调度
#define TASK_STOPPED 4 //暂停状态,0.11没有实现
Signal是任务接受到的信号图表,每一位代表一个信号,0表示没有信号,1表示有信号,blocked是任务当前屏蔽的信号图表,0表示没有屏蔽,1表示屏蔽信号。
alarm是alarm信号。
任务调度是,从最后一个任务到第一个任务遍历,如果当前任务号对应的任务存在,则处理信号。先处理alarm信号,如果alarm信号存在,则在signal中置位,清楚alarm值,在这里,alarm值应该是从开机到定时器触发的滴答数,而jiffies是从开机到现在的滴答数,这样alarm < jiffies 表示的就是已经超过了定时器的触发时间。
如果还有其他未被屏蔽的信号存在,并且任务的状态为可中断睡眠状态,将进程设为就绪状态,等待调度执行。
if (*p) { if ((*p)->alarm&& (*p)->alarm< jiffies) { (*p)->signal|= (1<<(SIGALRM-1)); (*p)->alarm =0; } if (((*p)->signal& ~(_BLOCKABLE & (*p)->blocked))&& (*p)->state==TASK_INTERRUPTIBLE) (*p)->state=TASK_RUNNING; }
下面的代码是任务的调度代码,主要是查询一个状态为就绪的,并且时间片最大的,且>0的任务执行,如果所有的任务时间片都为空了,重新分配所有任务的时间片,这里counter = counter /2 + priority,此时就绪状态的任务counter已经为0,但睡眠状态的任务不一定为0,所有重新分配时间片就是按照权值大小重新赋值:
while (1) { c = -1; next = 0; i = NR_TASKS;// NR_TASKS==64; p =&task[NR_TASKS]; while (--i) { //从最后一个任务,63号任务开始,倒序遍历 if(!*--p) continue; if((*p)->state == TASK_RUNNING && (*p)->counter > c) c= (*p)->counter, next = i; } if(c) break; //在sched.h当中,#defineFIRST_TASK task[0]// #defineLAST_TASK task[NR_TASKS-1] for(p= &LAST_TASK ; p > &FIRST_TASK ; --p) if(*p) (*p)->counter= ((*p)->counter >> 1) + (*p)->priority; }
找到相应的任务后,执行switch_to(next);切换到要调度的任务。
- linux 0.11 任务调度schedule
- OpenMP中的任务调度----schedule()
- 解析spring schedule 任务调度
- Spring Schedule 任务调度实现
- Linux-0.11 任务调度
- linux 调度 schedule分析
- Linux schedule 2、调度算法
- LINUX任务调度
- Linux任务调度
- linux任务调度命令
- linux任务调度学习
- linux 任务调度机制
- Linux crontab任务调度
- Linux 任务调度命令
- Linux 任务调度策略
- linux 任务调度
- linux 任务调度命令
- linux任务调度机制
- 装饰模式
- 2G-3G-4G网络结构演进过程
- 理解虚基类、虚函数与纯虚函数的概念
- 怎样远程登录局域网内其他计算机
- HQL中的内连接、左连接、右连接
- linux 0.11 任务调度schedule
- settimeout 作用域问题
- 摩托车继承自行车和机动车
- epoll处理
- 【双进程动规问题】NYOJ 61传纸条
- 数组中只出现1次的两个数字
- linux设备文件和普通文件
- 第十二周项目4-日期时间类
- 求最大公约数的两种方法