3

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

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

我想我错过了一些东西,可能是以下两个选项之一:(1)状态的实际变化只发生在我们调用 schedule() 时,或者(2)我们没有办法被安排出来(要么在 set_current_state 调用之后和 schedule() 调用之前,通过抢占、中断等。

感谢您的帮助!

4

3 回答 3

2

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

于 2012-12-21T10:33:23.860 回答
0

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

正如代码注释的那样,这是为了在处理器之间迁移,所以大概不会经常运行(相对而言)。

于 2012-12-21T10:03:24.730 回答
0

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

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

从链接引用,

[引用-]

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

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

于 2016-06-24T04:29:23.387 回答