Каков алгоритм позади сна ()?

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

41
задан kristianp 30 April 2012 в 04:47
поделиться

7 ответов

"Обновление" вопроса показывает некоторое неверное толкование как современная работа OSs.

ядру не "позволяют" интервал времени. Ядро является вещью, которая выделяет интервалы времени к пользовательским процессам. "Таймер" не установлен разбудить ждущий процесс - это установлено остановить в настоящее время рабочий процесс.

В сущности, ядро пытается справедливо распределить процессорное время путем остановки процессов, которые находятся на ЦП слишком долго. Для упрощенного изображения, скажем, что никакому процессу не позволяют использовать ЦП больше чем 2 миллисекунды. Так, ядро установило бы таймер на 2 миллисекунды и позволило бы выполненному процессу. Когда таймер запускает прерывание, ядро получает контроль. Это сохраняет текущее состояние рабочего процесса (регистры, указатель команд и так далее), и управление не возвращается к нему. Вместо этого другой процесс выбран из списка процессов, ожидающих, чтобы быть данным ЦП, и процесс, который был прерван, переходит к концу очереди.

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

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

39
ответ дан Joe F 27 November 2019 в 00:13
поделиться

Существует структура данных ядра, названная очередью сна. Это - приоритетная очередь. Каждый раз, когда процесс добавляется к очереди сна, время истечения срока процесса most-soon-to-be-awakened вычисляется, и таймер установлен. В то время на работу с истекшим сроком устраиваются от очереди и выполнения резюме процесса.

(забавные мелочи: в более старых реализациях Unix была очередь для процессов, для которых ветвление () назвали, но для которого не был создан дочерний процесс. Это, конечно, назвали очередь ветвления .)

HTH!

35
ответ дан Mark Harrison 27 November 2019 в 00:13
поделиться

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

, Что является процессом:

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

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

Процессы проводят много времени, спя (иначе ожидающий)

, процесс А проводит большую часть своего времени, ожидая. Например, процесс, который читает или пишет в диск, проведет много времени, ожидая данных, чтобы прибыть или, как признавать, отсутствовать на диске. Люди ОС используют термины "ожидание" и "сон" (и "заблокированный") несколько попеременно - все подразумевающие, что процесс ждет чего-то для случая, прежде чем это сможет продолжить свой веселый путь. Это просто сбивает с толку, что сон API ОС (), оказывается, использует базовые механизмы ОС для ждущих процессов.

Процессы могут ожидать других вещей: сетевые пакеты для прибытия, события выбора окна или таймер для истечения, например.

Процессы и Процессы Планирования

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

Планирование:

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

Очередь Таймера компьютер А имеет таймер в нем. Существует много способов, которыми это может быть реализовано, но классический способ называют периодический таймер . Периодический таймер отсчитывает в равном интервале - в большинстве операционных систем сегодня, я полагаю, что этот уровень 100 раз в секунду - 100 Гц - каждые 10 миллисекунд. Я буду использовать то значение в дальнейшем в качестве конкретного уровня, но знать, что большинство достойных операционных систем может быть настроено с различными галочками - и многие не используют этот механизм и могут обеспечить намного лучшую точность таймера. Но я отступаю.

Каждая галочка приводит к прерыванию к операционной системе.

, Когда ОС обрабатывает это прерывание по таймеру, она увеличивает свою идею системного времени еще на 10 мс. Затем это смотрит на очередь таймера и решает, с какими событиями на той очереди нужно иметь дело.

очередь таймера действительно очередь "вещей, с которыми нужно иметь дело с", который мы будем события вызова. Этой очереди приказывает время истечения, как можно скорее события сначала.

"событие" может быть чем-то как, "разбудите процесс X", или "идут дисковый ввод-вывод удара туда, потому что это, возможно, застряло", или "отсылают пакет проверки активности на этом ссылка fibrechannel там". Независимо от того, что операционная система должна сделать.

, Когда Вам приказали очередь таким образом, легко справиться с исключением из очереди. ОС просто смотрит во главе очереди и постепенно уменьшает "время к истечению" события на 10 мс каждая галочка. Когда время истечения срока переходит к нулю, ОС исключает то событие из очереди и делает то, что требуется.

В случае ждущего процесса, это просто делает процесс выполнимым снова.

Простой, ха?

15
ответ дан bog 27 November 2019 в 00:13
поделиться

существует по крайней мере два разных уровня для ответа на этот вопрос. (и много других вещей, которые запутываются с ним, я не коснусь их)

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

  2. уровень ядра. когда ОС не имеет ничего, чтобы сделать прямо сейчас, она выполняет инструкцию 'по hlt'. эта инструкция ничего не делает, но она никогда не заканчивается отдельно. Конечно, аппаратное прерывание обычно обслуживается. Помещенный просто, основной цикл ОС похож на это (от очень очень далеко):

    allow_interrupts ();
    while (true) {
      hlt;
      check_todo_queues ();
    }
    

    обработчики прерываний simpy добавляют вещи к todo очередям. Часы реального времени программируются для генерации прерываний любой периодически (по фиксированной процентной ставке), или к некоторому установленному времени в будущем, когда следующий процесс хочет быть, просыпаются.

10
ответ дан Javier 27 November 2019 в 00:13
поделиться

Многозадачная операционная система имеет компонент, названный планировщиком, этот компонент ответственен за предоставление процессорного времени к потокам, называть сон говорит ОС не давать процессорное время этому потоку в течение некоторого времени.

см. http://en.wikipedia.org/wiki/Process_states для полных деталей.

9
ответ дан Nir 27 November 2019 в 00:13
поделиться

Я ничего не знаю о Linux, но я могу сказать Вам, что происходит в Windows.

Сон () заставляет интервал процесса закончиться сразу для возврата управления ОС. ОС тогда настраивает объект ядра таймера, который сообщен после того, как время протекает. ОС не будет тогда давать тому процессу больше время, пока объект ядра не будет сообщен. Даже тогда, если другие процессы имеют выше или равняются приоритету, он может все еще ожидать некоторое время прежде, чем позволить процессу продолжиться.

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

8
ответ дан MattW. 27 November 2019 в 00:13
поделиться

По сути, да, есть «особая штуковина» - и она важна не только для сна ().

Классически на x86 это был Intel 8253 или 8254 » Программируемый интервальный таймер ». В ранних ПК это был отдельный чип на материнской плате, который мог быть запрограммирован ЦП для выдачи прерывания (через «Программируемый контроллер прерываний», другой дискретный чип) после заданного интервала времени. Функциональность все еще существует, хотя теперь это крошечная часть гораздо большего фрагмента схемотехники материнской платы.

Сегодня ОС по-прежнему программирует PIT, чтобы он регулярно будил его (в последних версиях Linux, по умолчанию, раз в миллисекунду) и именно так ядро ​​может реализовать упреждающую многозадачность.

5
ответ дан 27 November 2019 в 00:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: