Флуктуации отсчета времени
Флуктуации отсчета времени
Существует еще одно явление, которое вы должны принимать во внимание. Предположим, что разрешающая способность у вас равна 10 миллисекундам, а вы желаете сформировать задержку длительностью в 20 миллисекунд.
Всегда ли вы можете быть уверены, что от момента вызова функции delay() до возврата из нее пройдет ровно 20 миллисекунд?
Никогда.
На это есть две серьезные причины. Первая причина довольно проста: при блокировании поток изымается из очереди готовности. Это означает, что процессор может перейти к другому потоку вашего приоритета. Когда ваши 20 миллисекунд истекут, ваш поток будет помещен в конец очереди готовности по этому приоритету и будет таким образом оставлен на милость потока, выполняющегося в данный момент. Это относится также к обработчикам прерываний и к потокам более высокого приоритета — то, что ваш поток перешел в состояние READY, еще не означает, что ему сразу предоставят процессор.
Вторая причина несколько более хитрая. Чтобы понять ее смысл, посмотрите на нижеприведенный рисунок.
Флуктуации отсчета времени.
Проблема здесь состоит в том, что ваш запрос является асинхронным по отношению к источнику отсчетов. У вас нет никакой возможности синхронизировать аппаратный таймер с вашим запросом. Поэтому в итоге вы получите интервал задержки где-то в диапазоне от 20 до 30 мс — в зависимости от того, в какой момент между отсчетами аппаратных часов возник ваш запрос.
Это очень важный момент. Флуктуации отсчета времени — одна из печальных жизненных реалий. Единственный способ избавиться от этой проблемы заключается в увеличении разрешающей способности так, чтобы получающиеся погрешности укладывались в пределы установленных допусков. (Как это делается, мы рассмотрим ниже, в разделе «Опрос и установка часов реального времени».). Имейте в виду, что флуктуации проявляются только на первом отсчете таймера — задержка на 100 секунд, реализуемая с помощью таймера с разрешением в 10 мс, попадет в интервал между 100 и 100.01 секундами.