分享
 
 
 

Linux 2.4进程调度分析 5

王朝system·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

2. 调度器工作时机

调度器的启动通常有两种方式:

A. 主动式

在核心应用中直接调用schedule()。这通常发生在因等待核心事件而需要将进程置于挂起(休眠)状态的时候--这时应该主动请求调度以方便其他进程使用CPU。下面就是一个主动调度的例子:

/* 节选自[drivers/input/mousedev.c] mousedev_read() */

add_wait_queue(&list->mousedev->wait, &wait);

current->state = TASK_INTERRUPTIBLE;

while (!list->ready) {

if (file->f_flags & O_NONBLOCK) {

retval = -EAGAIN;

break;

}

if (signal_pending(current)) {

retval = -ERESTARTSYS;

break;

}

schedule();

}

current->state = TASK_RUNNING; /* 这一句实际上可以省略,因为进程的状态在唤醒过程中就已经恢复到TASK_RUNNING了 */

remove_wait_queue(&list->mousedev->wait, &wait);

其过程通常可分为四步:

将进程添加到事件等待队列中;

置进程状态为TASK_INTERRUPTIBLE(或TASK_UNINTERRUPTIBLE);

在循环中检查等待条件是否满足,不满足则调用schedule(),满足了就退出循环;

将进程从事件等待队列中删除。

从"调度器工作流程"中我们知道,调度器会将处于休眠状态的进程从就绪队列中删除,而只有就绪队列中的进程才有可能被调度到。将该进程重新放到就绪队列中的动作是在事件发生时的"唤醒"过程中完成的。在以上所示的鼠标驱动中,鼠标中断将调用mousedev_event()函数,该函数的最后就会使用wake_up_interruptible()唤醒等待鼠标事件的所有进程。wake_up_interruptible()将最终调用try_to_wake_up()函数:

/* 节选自[kernel/sched.c] */

static inline int try_to_wake_up(struct task_struct * p, int synchronous)

{

unsigned long flags;

int success = 0;

spin_lock_irqsave(&runqueue_lock, flags);

p->state = TASK_RUNNING;

if (task_on_runqueue(p))

goto out;

add_to_runqueue(p); /* 添加到就绪队列中 */

if (!synchronous || !(p->cpus_allowed & (1 << smp_processor_id())))

reschedule_idle(p); /* 这种情况下调用wake_up(),synchronous总为0,此时,*/

/* 如果本CPU不适合运行该进程,则需要调用reschedule_idle()寻找合适的CPU */

success = 1;

out:

spin_unlock_irqrestore(&runqueue_lock, flags);

return success;

}

这时启动schedule()就是被动的了。

B. 被动式

在系统调用执行结束后,控制由核心态返回到用户态之前,Linux都将在ret_from_sys_call入口检查当前进程的need_resched值,如果该值为1,则调用schedule():

/* 节选自[arch/i386/kernel/entry.S] */

ENTRY(ret_from_sys_call)

cli

cmpl $0,need_resched(%ebx) #ebx中存放着current指针

jne reschedule

……

reschedule:

call SYMBOL_NAME(schedule)

jmp ret_from_sys_call #反复查询need_resched

因此,只需要设置当前进程(current)的need_resched,就有机会启动调度器。通常有如下几种场合会设置need_resched:

update_process_times(),由时钟中断触发,负责管理除0号进程(idle进程)以外的其他各个进程的时间片消耗。如果当前进程(SCHED_FIFO实时进程除外)的时间片用完了(counter==0),则设置need_resched为1;(注意:此时并不计算或重置counter值,这个工作在所有进程的时间片都耗完以后在schedule()中进行)

reschedule_idle(),此函数的功能在"调度器工作流程"一节中已经详细描述了,不过,最经常的调用者是在某一事件等待队列上休眠的进程的唤醒过程--wake_up_process()及其他一系列wake_up函数(见上"主动式调度");

sched_setscheduler()、sched_yield()系统调用,以及系统初始化(rest_init()中)、创建新进程(do_fork()中)等从语义上就希望启动调度器工作的场合。

由于启动schedule()的时机实际上由当前进程决定,因此设置了need_resched并不意味着就能及时调度,这也是"Linux内核不可抢占"的原因(详见下"Linux 2.4调度系统的一些问题"之"内核不可抢占")。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有