Насколько я понимаю, запущенные процессы (и драйверы и т. д.) помещаются в очередь ожидания, когда им нужно дождаться ресурса, который может быть еще недоступен. Я знаю, что это можно сделать, вручную запустив ядро и поставив себя в очередь ожидания, пока ресурс не станет доступным.
Итак, мой вопрос: помещаются ли какие-либо процессы в очередь ожидания без явного входа в нее кода? И если да, то как ядро определяет, что процесс на самом деле нужно поместить в очередь ожидания или он хочет дождаться ресурса, а не продолжать выполнение без него и т. д.?
В основном спрашивают в отношении Linux, но если что-то подобное делается в каком-то другом ядре/операционной системе, мне было бы не менее интересно узнать, как это сделать.
@stark Вы говорите, что во время этого процесс можно поставить в очередь ожидания? Я уже знаю, что прерывание таймера переназначает процессы и переключает контекст в зависимости от уровня приоритета и т. д., но на самом деле это не отвечает на мой вопрос.
Если процесс использует свой квант времени и есть другие запущенные процессы, то да.
@stark Разве это не вернет его обратно в очередь выполнения и, возможно, изменит уровни приоритета?
Может быть, вы правы. Я думаю, что он остается в очереди на выполнение, если он все еще помечен как работающий. Я думал, что он будет ждать тикания таймера, но это может быть мое плохое воспоминание.
Я думаю, что в контексте ядра задача должна сделать что-то спящее, прежде чем ее можно будет вернуть в очередь выполнения. Если он просто сидит там в тугой петле, он просто будет висеть там. Планировщик сообщит в журнал ядра о зависании задачи.
@IanAbbott Вы имеете в виду, находится ли он в настоящее время в очереди на ожидание? Чтобы уточнить, когда я сказал «вернуться в очередь выполнения», я имел в виду переход от процессора, работающего в контексте процесса 1, а затем процесс 2 с более высоким приоритетом может занять его место, помещая процесс 1 «назад в очередь». Однако я могу использовать неправильные термины, если технически он не покидает очередь, становясь активным процессом.
«Помещаются ли какие-либо процессы в очередь ожидания без явного входа в нее кода?» - Нет, такого функционала нет.
@Tsyvarev Спасибо!
@STB Я имел в виду очередь выполнения, потому что «сделать что-нибудь спящее» просто означает сделать что-то, что может привести к тому, что задача заснет. Кроме того, я думаю, что то, что я описал, применимо только тогда, когда CONFIG_PREEMPT не определен. Для CONFIG_PREEMPT задачу можно снова поставить в очередь выполнения в любое время, пока задача в настоящее время является вытесняемой.
Нет, @Tsyvarev прав. Linux не будет перемещать процесс в очередь ожидания, пока процесс явно не выполнит операцию, которая приводит к перемещению в очередь ожидания.
Например, если процесс запрашивает ввод-вывод, то он может быть помещен в очередь ожидания, связанную с устройством ввода-вывода, пока выполняется ввод-вывод. Также возможно, что запрос ввода-вывода немедленно возвращается, если, например, ОС уже кэшировала файл, который процесс хочет прочитать, или если ОС буферизует запрос на запись.
Ожидание переменной условия — еще один пример запроса, который может привести к перемещению процесса в очередь ожидания, связанную с этой переменной условия.
Итак, мой вопрос: помещаются ли какие-либо процессы в очередь ожидания без явного входа в нее кода?
Не существует одной очереди ожидания ("очередь ожидания" и "очередь ожидания").
Вместо этого вы можете ожидать какую-то структуру данных (например, очередь ожидания) для каждого ресурса, которого может ожидать задача, например. может быть, по одному для каждого мьютекса, по одному для каждого канала, по одному для каждого сетевого сокета и т. д. Кроме того, для современных ядер (рассчитанных на большое количество ЦП) относительно распространено наличие еще большего количества очередей ожидания для улучшения масштабируемости и блокирования конкуренции - например. для чего-то вроде времени ("sleep()") у вас может быть одна очередь на каждый ЦП (вместо одной глобальной очереди, которую разделяют все ЦП).
Конечно, это тоже не так просто. Очередь ожидания может быть не очередью, а чем-то другим (например, деревом); и (в пределах разумного) может быть несколько ресурсов, связанных с очередью ожидания (например, вместо одного для каждого отдельного канала вы можете использовать подход хеш-таблицы и всегда иметь 4096 очередей независимо от того, сколько каналов есть).
Итак, мой вопрос: помещаются ли какие-либо процессы в очередь ожидания без явного входа в нее кода?
Да. Есть 2 случая, когда это очень вероятно:
а) у планировщика (когда задачи ждут процессорного времени) будет какое-то "ожидание чего-то" (дерево? Список для каждого приоритета потока?). Это мало чем отличается от любого другого случая — ЦП — это просто еще один ресурс, а ожидание ЦП — это просто ожидание ресурса.
б) трюки с виртуальной памятью. Например, если процессу нужно подождать, пока данные не будут извлечены из пространства подкачки (или из файла с отображением памяти, или ..), тогда процесс будет переведен в своего рода «ожидание чего-то».
Прерывание по таймеру изменит расписание процессов.