正常情况下很少会关注一个任务(进程或线程)的主动切换和被动切换的次数;但是当系统异常,例如任务很长时间得不到运行或者运行很慢的时候还是会看下切换的次数。
查看某个任务切换的次数,可以通过proc接口查看,例如查看任务pid的切换次数命令:
cat /proc/$pid/status | grep "ctxt_switches"
voluntary_ctxt_switches: 1241 /*进程主动切换的次数*/
nonvoluntary_ctxt_switches: 717 /*进程被动切换的次数*/
主动切换:任务主动调度是任务主动设置任务状态为TASK_INTERRUPTIBLE或者TASK_UNINTERRUPTIBLE后调用函数schedule()函数。
被动切换:任务处于TASK_RUNNING状态,调用函数schedule()函数。
相关的代码,在__schedule()函数中有代码:
-
switch_count = &prev->nivcsw; //switch_count设为被动切换计数字段的指针
-
if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) { //如果任务的状态不是 TASK_RUNNING,并且抢占没有生效
-
if (unlikely(signal_pending_state(prev->state, prev))) {
-
prev->state = TASK_RUNNING;
-
} else {
-
deactivate_task(rq, prev, DEQUEUE_SLEEP);
-
prev->on_rq = 0;
-
-
/*
-
* If a worker went to sleep, notify and ask workqueue
-
* whether it wants to wake up a task to maintain
-
* concurrency.
-
*/
-
if (prev->flags & PF_WQ_WORKER) {
-
struct task_struct *to_wakeup;
-
-
to_wakeup = wq_worker_sleeping(prev, cpu);
-
if (to_wakeup)
-
try_to_wake_up_local(to_wakeup);
-
}
-
}
-
switch_count = &prev->nvcsw; //switch_count设为主动切换计数字段的指针
-
}
-
if (task_on_rq_queued(prev))
-
update_rq_clock(rq);
-
-
next = pick_next_task(rq, prev);
-
clear_tsk_need_resched(prev);
-
clear_preempt_need_resched();
-
rq->clock_skip_update = 0;
-
-
if (likely(prev != next)) {
-
rq->nr_switches++;
-
rq->curr = next;
-
++*switch_count; //切换计数加1
-
-
rq = context_switch(rq, prev, next); /* unlocks the rq */
-
cpu = cpu_of(rq);
-
} else
-
raw_spin_unlock_irq(&rq->lock);
阅读(1743) | 评论(0) | 转发(0) |