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, по расписанию и запустить, как только планировщик позволяет ему.
наконец-то в пользовательском пространстве блокировка системного вызова возвращает с правильным состоянием и данными, и поток программы продолжается.
это можно вызвать большинство системных вызовов ввода-вывода в неблокирующий режим (см.
O_NONBLOCKinopen(2)иfcntl(2)). В этом случае системные вызовы немедленно возвращаются и сообщают только о правильной подаче дисковой операции. Программист должен будет явным образом проверить позже, завершена ли операция, с успехом или нет, и получить ее результат (например, сselect(2)). Это называется асинхронным или событийным программированием.большинство ответов здесь упомянуть состояние D (точное имя
TASK_UNINTERRUPTIBLEиз имен Linux sate) неверны. Элемент 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.
обычно процесс блокируется. Если операция чтения находится на файловом дескрипторе, отмеченном как неблокирующее, или если процесс использует асинхронный ввод-вывод, он не будет блокировать. Кроме того, если процесс имеет другие потоки, которые не заблокированы, они могут продолжать работать.
решение о том, какой процесс выполняется следующим до планировщик в ядре.
Comments