Состояния Процессов В Linux

в Linux, что происходит с состоянием процесса, когда ему нужно читать блоки с диска? Он заблокирован? Если да, то как выполняется другой процесс?

8 ответов


в ожидании read() или write() to / from a file descriptor return, процесс будет помещен в специальный вид сна, известный как"D" или "Disk Sleep". Это особенное, потому что процесс нельзя убить или прервать, находясь в таком состоянии. Процесс, ожидающий возвращения из ioctl (), также будет усыплен таким образом.

исключением из этого является то, когда файл (например, терминал или другое символьное устройство) открывается в O_NONBLOCK режим, переданный, когда его предполагается что для инициализации устройства (например, модема) потребуется время. Однако в своем вопросе вы указали блокирующие устройства. Кроме того, я никогда не пробовал ioctl() Это, вероятно, заблокирует на FD, открытом в неблокирующем режиме (по крайней мере, не сознательно).

выбор другого процесса полностью зависит от используемого планировщика, а также от того, какие другие процессы могли бы изменить свой вес в этом планировщике.

некоторые пользовательские космические программы под определенными известно, что обстоятельства остаются в этом состоянии навсегда, до перезагрузки. Они, как правило, группируются с другими "зомби", но термин не будет правильным, поскольку они не являются технически несуществующими.


когда процесс должен получить данные с диска, он эффективно перестает работать на процессоре, чтобы позволить другим процессам работать, потому что операция может занять много времени для завершения – по крайней мере, 5 мс время поиска для диска является общим, а 5 мс-10 миллионов циклов процессора, вечность с точки зрения программы!

С точки зрения программиста (также сказал, "в пространстве"), это называется блокировка системного вызова. Если вы позвоните write(2) (который является тонким libc обертка вокруг системного вызова с тем же именем), ваш процесс точно не останавливается на этой границе: он продолжает, на стороне ядра, запускать код системного вызова. Большую часть времени он идет до определенного драйвера контроллера диска (filename → filesystem/VFS → block device → device driver), где команда для извлечения блока на диске передается на соответствующее оборудование: это очень быстрая операция большую часть времени.

затем процесс помещается в спать государство (в пространстве ядра блокировка называется спящим-ничто никогда не "блокируется" с точки зрения ядра). Он будет разбужен снова, как только оборудование, наконец, извлекло правильные данные, то процесс будет отмечен как runnable, по расписанию и запустить, как только планировщик позволяет.

наконец-то в userspace блокировка системного вызова возвращает с надлежащим статусом и данными, и поток программы продолжается.

это возможно вызвать большинство системных вызовов ввода-вывода в неблокирующий режим (см. O_NONBLOCK на open(2) и fcntl(2)). В этом случае система вызывает return немедленно и сообщает только о правильной подаче дисковой операции. Программист должен будет явно проверить позже, завершена ли операция, с успехом или нет, и получить ее результат (например, с select(2)). Это называется асинхронным или основанным на событиях программированием.

большинство ответов здесь упомянуть D состояние (точное имя TASK_UNINTERRUPTIBLE из имен Linux sate) неверны. The D состояние-это специальный спящий режим, который запускается только в пути кода пространства ядра, когда этот путь кода нельзя прерывать (потому что это было бы сложно программировать), большую часть времени в надежде, что он будет блокировать очень скоро. Я считаю, что большинство "состояний D" на самом деле невидимы, они очень недолговечны и не могут наблюдаться с помощью инструментов выборки, таких как "верх".

но вы иногда будете сталкиваться с этими неубиваемыми процессами в состоянии D в нескольких ситуациях. NFS славится этим, и я сталкивался с этим много раз. Я думаю, что есть семантическое столкновение между некоторыми путями кода VFS, которые предполагают, что всегда достигают локальных дисков и быстрого обнаружения ошибок (на SATA тайм-аут ошибки будет около нескольких 100 мс), и NFS, который фактически извлекает данные из сети, которая более устойчива и имеет медленное восстановление (тайм-аут TCP 300 секунд общий.) Читать в этой статье для прохладного решения, представленного в Linux 2.6.25 с TASK_KILLABLE государство. До этой эры был взлом, где вы могли фактически отправлять сигналы клиентам процесса NFS, отправляя SIGKILL в поток ядра rpciod, но забудьте об этом уродливом трюке...


процесс, выполняющий ввод-вывод, будет помещен в состояние D (непрерывный сон), который освобождает процессор, пока не произойдет аппаратное прерывание, которое говорит процессору вернуться к выполнению программы. См.man ps для других состояний процесса.

в зависимости от вашего ядра, то есть планировщик процесса, который отслеживает runqueue процессов, готовых к выполнению. Это, наряду с алгоритмом планирования, сообщает ядру, какой процесс назначить ЦП. Необходимо учитывать процессы ядра и пользовательские процессы. Каждому процессу выделяется временной срез, который является куском времени процессора, который он может использовать. Как только процесс использует весь свой временной срез, он помечается как истекший и имеет более низкий приоритет в алгоритме планирования.

на ядро 2.6, есть сложностью O(1) планировщик времени, поэтому независимо от того, сколько процессов у вас работает, он будет назначать процессоры в постоянное время. Это сложнее, хотя, поскольку 2.6 ввел упреждение и балансировку нагрузки процессора не является простым алгоритмом. В любом случае, это эффективно, и процессоры не будут бездействовать, пока вы ждете ввода-вывода


как уже объясняли другие, процессы в состоянии " D " (бесперебойный сон) отвечают за зависание процесса ps. Со мной это случалось много раз с RedHat 6.X и автоматические домашние каталоги NFS.

чтобы перечислить процессы в состоянии D, вы можете использовать следующие команды:

cd /proc
for i in [0-9]*;do echo -n "$i :";cat $i/status |grep ^State;done|grep D

чтобы узнать текущий каталог процесса и, может быть, смонтированный диск NFS, который имеет проблемы, вы можете использовать команду, подобную следующему примеру (замените 31134 на номер спящего процесса):

# ls -l /proc/31134/cwd
lrwxrwxrwx 1 pippo users 0 Aug  2 16:25 /proc/31134/cwd -> /auto/pippo

я обнаружил, что предоставление команды umount с переключателем-f (force) в связанную смонтированную файловую систему nfs смогло разбудить спящий процесс:

umount -f /auto/pippo

файловая система не была размонтирована, потому что он был занят, но процесс пробуждения и я смог решить проблему без перезагрузки.


предполагая, что ваш процесс является одним потоком и что вы используете блокировку ввода-вывода, ваш процесс будет блокировать ожидание завершения ввода-вывода. Ядро выберет другой процесс для запуска в то же время на основе тонкости, приоритета, последнего времени выполнения и т. д. Если нет других выполняемых процессов, ядро не будет запускать их; вместо этого оно сообщит аппаратному обеспечению, что машина простаивает (что приведет к снижению энергопотребления).

процессы, ожидающие завершения ввода-вывода показать в состоянии D В, например,ps и top.


Да, задача блокируется в системном вызове read (). Другая задача, которая готова, выполняется, или если другие задачи не готовы, выполняется задача простоя (для этого процессора).

обычное, блокирующее чтение диска заставляет задачу войти в состояние " D " (как отмечали другие). Такие задачи способствуют средней нагрузке, даже если они не потребляют процессор.

некоторые другие типы ввода-вывода, особенно ttys и сеть, ведут себя не совсем так же-процесс заканчивается в состоянии " S " и может прерываться и не засчитывается в среднее значение нагрузки.


Да, задачи, ожидающие ввода-вывода, блокируются, а другие задачи выполняются. Выбор следующей задачи выполняется с помощью планировщик Linux.


Как правило, процесс будет блокировать. Если операция чтения на файловый дескриптор помечен как неблокирующий или если процесс использует асинхронный ввод / вывод, он не будет блокировать. Кроме того, если процесс имеет другие потоки, которые не заблокированы, они могут продолжать работать.

решение о том, какой процесс выполняется следующим до планировщик в ядре.