Энциклопедия разработчика модулей ядра Linux
Шрифт:
Отложенные
Что Вы делаете, когда кто-то просит Вас о чем-то, что Вы не можете сделать сразу же? Если вы человек, и вы обеспокоены, единственное, что Вы можете сказать: «Не сейчас, я занят.». Но если вы модуль, Вы имеете другую возможность. Вы можете поместить процесс в спячку, чтобы он бездействовал, пока Вы не сможете обслужить его. В конце концов, процессы помещаются в спячку и пробуждаются ядром постоянно.
Этот модуль является примером этого подхода. Файл (названный /proc/sleep) может быть открыт только одним процессом сразу. Если файл уже открыт, модуль называет module_interruptible_sleep_on [7] . Эта функция изменяет состояние задачи (задача является структурой данных в ядре, которая хранит информацию относительно процесса и системного вызова) в состояние TASK_INTERRUPTIBLE, что означает, что задача не будет выполняться пока не будет пробуждена так или иначе, и добавляет процесс к WaitQ, очереди задач ждущих, чтобы обратиться к файлу. Затем функция обращается к планировщику за контекстным переключателем другого процесса, который может использовать CPU, то есть управление передается другому процессу.
7
Самый простой способ держать файл открытым состоит в том, чтобы открыть его tail -f.
Когда процесс закончит работу с файлом, тот закрывается, и вызывается module_close. Эта функция пробуждает все процессы в очереди (нет никакого механизма, чтобы пробудить только одни из них). Управление возвращается и процесс, который только закрыл файл, может продолжать выполняться. Планировщик решает, что тот процесс поработал достаточно и передает управление другому процессу. В конечном счете, один из процессов, который был в очереди, получит управление. Он продолжит выполнение с той точки, в которой был вызван module_interruptible_sleep_on [8] . Он может установить глобальную переменную, чтобы сообщить всем другим процессам, что файл является все еще открытым. Когда другие процессы получат часть времени CPU, они увидят глобальную переменную и продолжат спячку.
8
Это означает, что процесс — все еще в ядерном режиме — насколько процесс затронут, он выдал системный вызов open и системный вызов все же не возвратился. Процесс не знает, что кто-то еще использовал CPU в течение времени между моментом, выдачи обращения и возвратом