另一个新手问题:
在下面的代码中,如果在调用'set_current_state'之后但在调用'schedule'之前线程被抢占了怎么办?再次安排代码时,是否从“schedule”调用开始并从运行队列中删除?或者这次忽略'schedule'调用并从set_current_state(TASK_RUNNING)语句开始?
{
...
set_current_state(TASK_INTERRUPTIBLE); /* suppose thread is preempted just after this function call */
schedule();
set_current_state(TASK_RUNNING);
...
}
答案 0 :(得分:6)
如果在第一行之后和第二行之前发生非自愿抢占,会发生什么(或多或少):
调度程序将运行(来自sched.c的scheduler()函数) - 因为这是被抢占的意思。
由于您的任务被标记为不可运行,因此调度程序会将其从运行队列中删除,并将选择其他任务。
现在您的任务将不会被安排,直到外部将其再次标记为可运行。这可能是由于发送到任务的信号,或者假设任务在等待队列中排队,由于唤醒队列属于发生的事件,但是外部必须将任务标记为可再次运行或者永远不会被安排。这就是为什么如果你查看等待队列代码,它首先将任务放在等待队列上,然后才会执行类似于你的代码。
当您的任务被标记为可运行时,调度程序将在某个时刻选择它并将上下文切换到任务代码。
然后调用schedule()函数。在很可能的情况下,调度程序将再次选择相同的任务,因为它刚被选中,因为它最适合运行,并且不太可能发生这种情况。
在从调度程序返回的路上,最后一个set_current_state基本上是一个无操作,因为此时的任务在这种情况下已被标记为可运行。