使用set_current_state在内核中休眠

时间:2012-12-21 09:54:52

标签: c linux multithreading kernel preemption

我一直在阅读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,我们将进程设置为sleep,并且在该行之后我们实际上被抢占/调度并且该进程也真正被发送到睡眠状态会发生什么?

在这种情况下,在更改状态之前就会收到唤醒呼叫(因此它不会影响我们),操作系统的正常操作会让我们在实际检查任何内容之前进入休眠状态。

我想我错过了一些东西,可能是以下两种选择之一: (1)状态的实际变化仅在我们调用schedule()时发生,或者(2)在set_current_state调用之后和调度之前,我们无法调度(通过抢占,中断,任何东西)( )打电话。

感谢您的帮助!

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

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

引用链接,

[报价 - ]

如果我理解正确,当发生先发制人时, PREEMPT_ACTIVE位被添加到线程的preempt_count;这个 发生在preempt_schedule / preempt_schedule_irq中。然后这些电话 schedule(),它检查在count和中设置的PREEMPT_ACTIVE 如果它已设置,它不会调用deactivate_task(),它会离开 活动列表上的线程。 [-quote]

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