分类:
2012-06-03 19:03:28
1、进程分为两类,一类为非抢占式多任务和抢占式多任务。Linux属于第二类系统,而且第一类系统不多见,如Mac
OS 9.
2、进程可以被分为IO消耗型和处理器消耗型,前者大部分时间用来提交IO请求,因此这样的进程处于可运行的状态,但通常都是运行了短暂的一会,因为它在等待更多的IO请求时最后总会阻塞,如键盘输入,相反,后者的进程把时间大多都用在了执行代码上了,如执行一个算法。
3、调度算法中最基本的一类“基于优先级的调度”,这是一种根据进行程的价值和其对处理器时间 的需求来进行分级的做法。优先级高的进程先运行,低的后运行,相同优先级的进程按轮转方式进行调度。在Linux中提供了一种动态优先级的调度方法,一开始先设置基本的优先级,然而它允许程序根据需要加减优先级。
3、时间片,是一个数值,它表明了进程在被抢占前所能持续运行的时间,默认的时间片为20MS。一般一个进程分配的时间片为10-200ms。
4、调度程序中最基本的数据结构是运行队列(runqueue),可执行队列定义于kernel/sched.c中,由runqueue表示,可执行队列是给定处理器上的可执行进程的链表,每一处理器一个,每个可投入运行的进程都唯一的归属于一个可执行队列。
5、
DECLARE_WAITQUEUE(wait,current);
add_wait_queue(q,&wait);//q为等待队列
set_current_state(TASK_INTERRUPTIBLE);
while(!condition)
schedule();
set_current_state();
remove_wait_queue(q,&wait);
进程通过以下步骤将自己加入到一个等待队列中:
A调用DECLARE_WAITQUEUE()创建一个等待队列;
B调用add_wait_queue()把自己加入到队列中,该队列在进程等待的条件满足时唤醒它,我们必需在其他的地方编写相关的代码,在事件发生时,对等待队列执行wake_up()操作;
C将进程的状态变为TASK_INTERRUPTIBLE或是TASK_UNINTERRUPTIBLE;
D检查条件是否为真,如果是的话,就没有必要休眠了,如果条件不为真,调用schedule();
E当进程被唤醒时,会再次检查条件是否为真,如果是,退出循环,如不是,再次会调用schedule()并一直重复这步操作;
F条件满足后,进程把自己设置为TASK_RUNNIG并调用remove_wait_queue()把自己移出等待队列。
以上过程很好的解释了宋宝华-驱动程序书164页的代码。
6、每个运行队列都有两个优先级数组,一个活跃的一个过期的。活跃数组内的可执行队列上的进程都还有时间片剩余,而过期的数组内的可执行队列上的进程都耗尽了时间片,当一个进程的时间 片耗尽时,它会被移到过期数组的队列上。
7、Linux通过sched_yield()系统调用(unistd.h),提供了一种让进程显式地将处理器时间让给其它等待执行进程的机制。它是通过将进程从活动队列中移到过期队列中实现的。