睡在内核使用set_current_state

我一直在阅读http://www.linuxjournal.com/article/8144,并想到以下情况:

4253 /* Wait for kthread_stop */ 4254 set_current_state(TASK_INTERRUPTIBLE); 4255 while (!kthread_should_stop()) { 4256 schedule(); 4257 set_current_state(TASK_INTERRUPTIBLE); 4258 } 4259 set_current_state(TASK_RUNNING); 4260 return 0; 

现在,如果在第4254行之前调用kthread_stop会发生什么情况,我们将进程设置为睡眠状态,在该行之后,我们实际上被抢占/调度,并且进程也被真正发送到睡眠状态?

在这种情况下,在改变状态之前接收唤醒电话(所以它不影响我们),并且在我们实际检查任何事情之前,操作系统的正常操作使我们睡眠。

我想我错过了一些东西,可能是以下两种select之一:(1)当我们调用schedule()或者(2)时,状态的实际改变只会发生,我们没有办法调出通过抢占,中断,任何事情)在set_current_state调用之后和schedule()调用之前。

感谢您的帮助!

如果在第4254行之前调用kthread_stop ,则kthread_should_stop()将返回true,并且不会调用schedule() 。 在这个特定的情况下, migration_thread被调度具有SCHED_FIFO策略 (没有时间片)的高优先级 ,并且只能被具有更高优先级的另一个SCHED_FIFO任务抢先(见sched_setscheduler )。

schedule()是Linux内核在线程之间改变上下文的唯一方式。

正如代码所述,这是为了在处理器之间进行迁移,所以可能不会经常运行(相对而言)。

这是一个类似的问题和答案

http://fixunix.com/linux/7425-schedule_timeout-doubt-possible-infinite-sleep.html

从链接引用,

[引用-]

如果我理解正确,当发生抢占时,PREEMPT_ACTIVE位将被添加到线程的preempt_count; 这发生在preempt_schedule / preempt_schedule_irq中。 然后调用schedule()来检查PREEMPT_ACTIVE是否在count中被设置,如果被设置,它不会调用deactivate_task(),这会将线程留在活动列表中。 [-引用]

所以如果发生中断或抢占,线程将不会被移出运行队列。