Нужно ли вызывать set_current_state (TASK_INTERRUPTIBLE) перед вызовом расписания? - PullRequest
1 голос
/ 23 сентября 2019

Нужно ли мне вызывать set_current_state() перед вызовом schedule(), чтобы запланировать следующий процесс из очереди выполнения?

Я видел много кода, где функция потока ядра использует set_current_state() для установкисостояние TASK_RUNNING или TASK_UNINTERRUPTIBLE.

set_current_state(TASK_INTERRUPTIBLE);

while (!kthread_should_stop()) {
        ....
        schedule();
        .....
}
__set_current_state(TASK_RUNNING);

Необходимо ли вызвать set_current_state() с TASK_INTERRUPTIBLE перед вызовом schedule()?

В этом примере кода, чтоявляется ли использование установки состояния TASK_RUNNING после того, как оно выходит из цикла kthread_should_stop()?

1 Ответ

4 голосов
/ 23 сентября 2019

Да, вы должны вызвать set_current_state() перед вызовом schedule(), потому что в противном случае планировщик не удалит задачу из очереди выполнения (если вы просто хотите, чтобы другие задачи могли выполняться без перехода в спящий режим, вам следуетвместо этого вызывается cond_resched()).

Заданное вами состояние задачи зависит от того, хотите ли вы проснуться от сигналов или нет:

  • TASK_UNINTERRUPTIBLE не разбудило сигналы;
  • TASK_KILLABLE пробуждается только смертельными сигналами;
  • TASK_INTERRUPTIBLE пробуждается любым сигналом.

Кроме того, TASK_IDLE похож на TASK_UNINTERRUPTIBLEно не влияет на среднюю загрузку.

Причина, по которой код устанавливает состояние обратно в TASK_RUNNING, заключается в том, что kthread_should_stop() мог вернуть значение true на первой итерации цикла while(), поэтому schedule() никогда не вызывался (вам не нужно возвращать состояние задачи обратно в TASK_RUNNING после возврата из schedule()).

Обычно вы будете ждать в очереди ожидания, в этом случае вы не делаетенеобходимо непосредственно установить состояние задачи - вместо этого вы можетеse помощники в очереди ожидания в виде как:

DEFINE_WAIT(wait);

prepare_to_wait(waitqueue, &wait, TASK_UNINTERRUPTIBLE);
schedule();
finish_wait(waitqueue, &wait);
...