在schedule()之后恢复线程

Alb*_*ert 2 linux-kernel

另一个新手问题:

在下面的代码中,如果在调用'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);
...
} 
Run Code Online (Sandbox Code Playgroud)

gby*_*gby 6

这里(或多或少)如果在第一行之后和第二行之前发生非自愿抢占将会发生什么:

  1. 调度程序将运行(来自sched.c的scheduler()函数) - 因为这是被抢占的意思.

  2. 由于您的任务被标记为不可运行,因此调度程序将其从运行队列中删除,并将选择另一个任务.

  3. 现在,在外部将其标记为可再次运行之前,您的任务将不会被安排.这可能是由于发送到任务的信号,或者假设任务在等待队列中排队,由于唤醒队列属于发生的事件,但是外部必须将任务标记为可再次运行或者永远不会被安排.这就是为什么如果你查看等待队列代码,它首先将任务放在等待队列上,然后才会执行类似于你的代码.

  4. 当您的任务被标记为可运行时,调度程序将在某个时刻选择它并将上下文切换到任务代码.

  5. 然后调用schedule()函数.在很可能的情况下,调度程序将再次选择相同的任务,因为它刚刚被它选中,因为它最适合运行,并且它不太可能已经改变.

  6. 在从调度程序返回的路上,最后一个set_current_state基本上是一个无操作,因为此时的任务已在此方案中标记为可运行.