• Ограничения реального времени. Встроенную систему можно отнести к системам с жесткими условиями реального времени (hard real time), если она должна всегда давать ответ до наступления заданного срока. Если она должна давать ответ до наступления заданного срока лишь в большинстве случаев, а иногда может позволить себе просрочить время, то такую систему можно отнести к системам с мягкими условиями реального времени. Примерами систем с мягкими условиями реального времени являются контроллеры автомобильных окон и усилитель стереосистемы. Обычный человек все равно не заметит миллисекундной задержки в движении стекол, и только опытный слушатель способен уловить миллисекундное изменение высоты звука. Примером системы с жесткими условиями реального времени является инжектор топлива, который должен впрыскивать бензин в точно заданные моменты времени с учетом движения поршня. Если произойдет хотя бы миллисекундная задержка, то мощность двигателя упадет и он станет портиться; в итоге двигатель может выйти из строя, что, возможно, повлечет за собой дорожное происшествие или катастрофу.
• Предсказуемость. Это ключевое понятие во встроенных системах. Очевидно, что этот термин имеет много интуитивных толкований, но здесь — в контексте программирования встроенных систем — мы используем лишь техническое значение: операция считается предсказуемой (predictable), если на данном компьютере она всегда выполняется за одно и то же время и если все такие операции выполняются за одно и то же время. Например, если x
и y
— целочисленные переменные, то инструкция x+y всегда будет выполняться за фиксированное время, а инструкция xx+yy
будет выполняться за точно такое же время, при условии, что xx
и yy
— две другие целочисленные переменные. Как правило, можно пренебречь небольшими колебаниями скорости выполнения операции, связанными с машинной архитектурой (например, отклонениями, вызванными особенностями кэширования и конвейерной обработки), и просто ориентироваться на верхний предел заданного времени. Непредсказуемые операции (в данном смысле этого слова) нельзя использовать в системах с жесткими условиями реального времени и можно лишь с очень большой осторожностью применять в остальных системах реального времени. Классическим примером непредсказуемой операции является линейный поиск по списку (например, выполнение функции find()
), если количество элементов списка неизвестно и не может быть легко оценено сверху. Такой поиск можно применять в системах с жесткими условиями реального времени, только если мы можем надежно предсказать количество или хотя бы максимальное количество элементов списка. Иначе говоря, для того чтобы гарантировать, что ответ поступит в течение фиксированного интервала времени, мы должны — возможно, с помощью инструментов анализа кода — вычислить время, необходимое для выполнения любой последовательности команд, приводящих к исчерпанию запаса времени.
• Параллелизм. Встроенные системы обычно реагируют на события, происходящие во внешнем мире. Это значит, что в программе многие события могут происходить одновременно, поскольку они соответствуют событиям в реальном мире, которые могут происходить одновременно. Программа, одновременно выполняющая несколько действий, называется параллельной (concurrent, parallel). К сожалению эта очень интересная, трудная и важная тема выходит за рамки рассмотрения нашей книги.
25.2.1. Предсказуемость
С точки зрения предсказуемости язык С++ очень хорош, но не идеален. Практически все средства языка С++ (включая вызовы виртуальных функций) вполне предсказуемы, за исключением указанных ниже.
• Выделение свободной памяти с помощью операторов new
и delete
(см. раздел 25.3).
• Исключения (раздел 19.5).
• Оператор dynamic_cast
(раздел A.5.7).
В приложениях с жесткими условиями реального времени эти средства использовать не следует. Проблемы, связанные с операторами new
и delete
, подробно описаны в разделе 25.3; они носят принципиальный характер. Обратите внимание на то, что класс string
из стандартной библиотеки и стандартные контейнеры (vector
, map
и др.) неявно используют свободную память, поэтому они также непредсказуемы. Проблема с оператором dynamic_cast
связана с трудностями его параллельной реализации, но не является фундаментальной.