В развитие ответа Жиля,
Q2: Я не уверен, но я бы интерпретировал отрывок из книги
означает, что обработчик прерывания вызывает wake_up()
один раз
(передавая идентификатор очереди в качестве аргумента), а wake_up()
вызывает try_to_wake_up()
для каждого процесса, находящегося в этой очереди.
(Это повторяет ответ Жиля на Q1:
он не будит все задачи, а только те, которые находятся в очереди ожидания
связанные с событием, вызвавшим wake_up()
.)
Q3: Каждая очередь ожидания "принадлежит" некоторой части кода ядра -
в основном драйверы устройств, некоторые другие.
Процедура, владеющая очередью, присваивает ей уникальный идентификатор,
основанному на некоторой уникальной характеристике события, для которого предназначена очередь.
Когда она (драйвер/другой модуль) переводит процесс в спящий режим,
он указывает (по идентификатору), в какую очередь его поместить.
Процедура, вызывающая wake_up()
(обычно обработчик прерывания)
должна быть частью того же модуля, который перевел процесс в спящий режим,
поэтому он знает идентификатор очереди.
которая соответствует произошедшему событию.
Последний раз, когда я смотрел на исходный код ядра Unix (а это было много лет назад), у дисковых драйверов был свой идентификатор события для каждого запроса ввода-вывода. Как говорит Жиль, несколько процессов могут ожидать одного и того же события. если они читают один и тот же файл в одно и то же время. (Это, конечно, также относится к Q1.)
Q4: Когда я слышу фразу "контроллер диска", я думаю об аппаратном обеспечении.
Но, кроме этого, вы правы; дисковый драйвер
(программный модуль в ядре) имеет (по крайней мере, потенциально)
доступ к всей информации о любом процессе, который вызывает его
(то есть, выполняя дисковый ввод-вывод).
Поэтому, когда дисковый драйвер переводит процесс в спящий режим.
потому что он инициировал физический ввод/вывод, который требует времени для завершения,
он (драйвер) помещает "PID процесса, адрес памяти или что-то еще"
в очередь ожидания.
Что бы это ни было, этого достаточно для try_to_wake_up()
, чтобы разбудить процесс.
Последнее предложение цитируемого вами отрывка гласит,
"... VFS вызывает wake_up() на очереди ожидания ...".
Я сомневаюсь, что это дословно.
Код файловой системы находится на уровень выше драйвера диска.
Я бы ожидал, что прерывание (сигнал от дискового оборудования к CPU)
будет обработано обработчиком дискового прерывания (часть дискового драйвера).
который разбудит ожидающий процесс(ы)
(путем вызова wake_up()
).
Впоследствии драйвер разбудит код файловой системы.
(Эта терминология также может быть неточной.
Возможно, лучше сказать, что драйвер делает что-то.
чтобы позволить коду файловой системы возобновить обработку.)
Затем код файловой системы может вернуться в пользовательский процесс,
или снова вызвать драйвер диска,
в результате чего процесс снова будет переведен в спящий режим.
Я спорю с вашим шагом №4. Если устройство использует DMA, оно не будет прерываться до тех пор, пока не завершится передача данных.
-dmS просто принудительно выполняет следующие действия:
-dm
-S sessioname
Запуск в качестве демона означает, что он будет выполнять указанную команду в фоновом режиме до завершения выполнения.
Начальный экран, запуск команды и отсоединение должны иметь такое же поведение, как и использование -dmS для запуска команды. Я часто запускаю игровые серверы или длинные задания, запустив экран, а затем отключившись с помощью Ctrl-A + d
. Вы также можете проверить страницы руководства экран руководства
для получения более подробной информации о параметрах.
Вы должны использовать -dm
, только если вы хотите запустить команду в сеансе экрана, а не вводить ее в интерактивном режиме
- S
просто дает сеансу удобное имя, чтобы вы могли легко повторно подключиться к нему позже
. Если вы хотите использовать его в интерактивном режиме и не хотите давать ему удобочитаемое имя, вы можете опустить все эти аргументы безопасно.
Например, если вы просто хотите запустить экран
для выполнения команды, скажем, / path / to / longTime
, и вы не хотите смотреть, как она запускает вас можно было бы сделать это либо как
screen -dmS longSession /path/to/longTime
, либо вы могли бы сделать
screen -S longSession
$ /path/to/longTime
ctrl a d
И то, и другое сделало бы одно и то же, но для одного проще написать сценарий и немного меньше печатать.
Это более полезно как screen -dmS name command args
- это запустит сеанс экрана под названием name
в фоновом режиме (т.е. отделенный), и запустит command args
внутри этого сеанса.
Без command args
будет просто запущена экранная сессия в фоновом режиме.
В любом случае, вы можете подключиться к этому сеансу позже, например, screen -d -r name
. Из man screen
:
-d|-D [pid.tty.host]
не запускает screen, а отсоединяет запущенную в другом месте сессию screen. Это имеет тот же эффект, что и ввод "C-a d" с управляющего терминала screen.
-D
- это эквивалент клавиши отсоединения питания. Если сеанс не может быть отключен, эта опция игнорируется. В сочетании с опциями-r
/-R
можно добиться более мощных эффектов:
-d -r
Повторное присоединение сеанса и, если необходимо, первое его отсоединение.
-d -R
Повторное присоединение сессии и, если необходимо, ее отсоединение или даже создание.
-d -RR
Отсоедините сессию и, если необходимо, отсоедините или создайте ее. Используйте первую сессию, если доступно более одной сессии.
-D -r
Повторное подключение сеанса. При необходимости сначала отсоедините и выйдите из системы удаленно.
-D -R
Прикрепить здесь и сейчас. В деталях это означает: Если сессия запущена, то прикрепить. При необходимости сначала отсоединитесь и выйдите удаленно. Если сессия не запущена, то создать ее и уведомить пользователя. Это любимый вариант автора.
-D -RR
Прикрепить здесь и сейчас. Что бы это ни значило, просто сделайте это.Примечание: Всегда полезно проверить состояние ваших сессий с помощью
screen -list
.
На этой странице руководства не хватает важной детали - она должна звучать так:
-d|-D [pid.tty.host|session name]