Ядро Linux в комментариях

       

Уменьшение случаев бегства


Как говорилось в , функция __wake_up (строка ) заставляет «проснуться» все процессы в очереди ожидания. Однако, представьте себе Web-сервер наподобие Apache, который пытается уменьшить время ответа, вызывая fork для ряда процессов, чтобы те отслеживали соединения на одном и том же порте (как альтернатива ожиданию прихода запроса на соединение и только затем— вызова fork для процесса). Все эти процессы попадают в очередь ожидания поступления запросов на соединения, и как только запросы поступают, процессы пробуждаются. Запрос может обслужить только один из них, поэтому все остальные процессы вновь погружаются в спячку.

Подобного рода «бегство» отымает лишние циклы ЦП — было бы лучше пробуждать только один процесс, который, собственно, и займется обслуживанием запроса. В этой связи и был введен новый разряд состояния задачи TASK_EXCLUSIVE; за одно обращение к __wake_up может пробуждаться максимум один процесс с установленным разрядом TASK_EXCLUSIVE. TASK_EXCLUSIVE — это не новое состояние задачи, а всего лишь дополнительный разряд в существующем состоянии задачи. Так сделано для удобства его использования.

Теперь __wake_up проверяет, установлен ли разряд TASK_EXCLUSIVE для пробуждаемого процесса, а затем прекращает пробуждать процессы после активизации данного (выходит из цикла по break). В настоящее время разряд TASK_EXCLUSIVE задействуется только в очередях ожидания, связанных с сетевой обработкой, и здесь он имеет хороший шанс прижиться. Для большинства других очередей все процессы должны получать мгновенные снимки в момент ожидания доступности ресурсов, что позволит избежать зависания. Однако, серверы, ожидающие на одном и том же порте, обычно находятся в том же положении, что и Apache: все ожидающие задачи идентичны, и все сводится к тому, что какая-то одна из задач будет обслуживать поступающий запрос, даже если это такой запрос, который требует обслуживания одной и той же задачей.



Содержание раздела