【问题标题】:Sleeping in the kernel using set_current_state使用 set_current_state 在内核中休眠
【发布时间】:2012-12-08 21:35:30
【问题描述】:

我一直在阅读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() 之前,我们无法被调度(通过抢占、中断等) ) 调用。

感谢您的帮助!

【问题讨论】:

    标签: c linux multithreading kernel preemption


    【解决方案1】:

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

    【讨论】:

    • 问题是如果我们在第 4254 行之后和第 4255 行之前被重新安排(由于正常消耗我们的时间片,或者因为发生了中断)会发生什么
    • @rmn:刚刚添加了额外的细节,虽然要点是,线程没有时间片。中断并不真正相关,因为没有理由重新安排。
    • 即使发生了重新安排,当完成后,我们会回到这段代码并像以前一样继续。因此没有什么特别的事情发生。您对此特定代码是否有一些特别的担忧,或者您只是想了解线程的调度等一般情况?请记住,这是 2.6 内核,我还没有查看 3.7.1 内核中的相应代码,这是我一直在工作的[远不及调度部分]
    • 当一个线程的状态设置为task_interruptible时,它不再是task_running,也不会被重新调度。所以我担心你们可能会错过我的意思..
    【解决方案2】:

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

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

    【讨论】:

    • 我不确定你是对的——中断和抢占(在你的时间片结束之后)呢?
    【解决方案3】:

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

    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(),这会留下 活动列表中的线程。 [-quote]

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-21
      • 2014-12-12
      • 2012-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-22
      相关资源
      最近更新 更多