Ядро может быть вытесняющим, а не планировщиком.
Первые sched_yield()
и wait()
являются типами добровольного вытеснения , когда сам процесс выдает ЦП, даже если ядро не имеет вытеснения.
Если ядро имеет возможность переключаться на другой процесс, когда квант времени истек или процесс с более высоким приоритетом становится работоспособным, тогда речь идет о невольном вытеснении , то есть вытесняющем ядре, и это может произойти наразличные места объяснены ниже.
Разница заключается в том, что в sched_yield()
процесс остается в состоянии выполнения TASK_RUNNING , но просто переходит в конец очереди выполнения для статического приоритета.Процесс должен ждать, чтобы снова получить процессор.
С другой стороны, wait()
переводит процесс в состояние сна TASK_ (UN) INTERRUPTABLE в очереди ожидания вызывает schedule()
и ожидает наступления события.Когда происходит событие, процесс снова перемещается для запуска очереди.Но это не значит, что они сразу получат процессор.
Здесь объясняется, когда schedule()
может быть вызвано после пробуждения процесса:
Пробуждения на самом деле не вызывают вход в расписание().Они добавляют задачу в очередь выполнения и все.Если новая задача, добавленная в очередь выполнения, вытесняет текущую задачу, тогда функция пробуждения устанавливает TIF_NEED_RESCHED, и schedule () вызывается при ближайшем возможном случае:
Если ядро выгружается (CONFIG_PREEMPT = y):
- в контексте системного вызова или исключения, при ближайшем следующем preempt_enable ().(это может произойти, как только функция spin_unlock ()!)
- в контексте IRQ вернется из обработчика прерываний в приоритетный контекст
Если ядро не выгружается (CONFIG_PREEMPT не установлено), то при следующем:
- вызов cond_resched ()
- явное расписание () вызов
- возврат изсистемный вызов или исключение из пользовательского пространства
- возврат из обработчика прерываний в пользовательское пространство