logo
ОСНОВЫ АСУ ТП

10.6.7. Приоритеты процессов и производительность системы

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

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

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

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

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

В развитых и сложных операционных системах, таких как UNIX и Windows NT, и в еще большей степени в распределенных операционных системах, доступ к большин­ству функций (ввод/вывод, сетевая поддержка и т. д.) происходит через системные вы­зовы или механизм удаленного вызова процедур (раздел 10.5.4). В прикладных програм­мах для вызова системных функций используется довольно простая нотация, за которой, как правило, стоит длинная последовательность действий операционной системы. Если между двумя процессами, исполняющимися в разных узлах сети, организован про­граммный канал, то считывание одного символа из этого канала требует целой серии операций в обоих узлах. Поскольку на эти операции обычно наложены жесткие ограни­чения по времени, необходимо провести глубокий предварительный анализ прежде, чем принимать то или иное проектное решение. Если локальная сеть используется не только задачами реального времени, но и интерактивными пользователями, то от количества и активности последних в значительной мере зависит и ее общая нагрузка.

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

10.6.8. Тестирование и отладка

Доказательство правильности работы программы является обязательным шагом в ее разработке. Необходимо проверить, что программа выполняет свои функции без ошибок. Визуальные и формальные методы позволяют выявить только ограниченное количество ошибок. На практике это означает, что формальная теория тестирования имеет мало смысла, а основную роль играет собственный опыт и "народные програм­мистские" предания. Реальное тестирование проводится в "боевых" условиях.

Выявлять ошибки трудно — многие из них проявляются спорадически и их нельзя воспроизвести по желанию. Никакое доказательство не может гарантировать, что программа полностью свободна от ошибок, и никакие тесты не могут убедить, что выявлены все ошибки. Цель тестирования — найти как можно большее число ошибок, гарантировать, что программа работает с разумной надежностью. Один из создателей теории операционных систем, Эдсгер Дейкстра (Edsger Dijkstra), заметил: "Тесрование может доказать только наличие ошибок, но не их отсутствие". Тщательный тест требует соответствующей разработки и подготовки; необходимое сочетание практических и аналитических тестов. Сначала тестовые процедуры и данные и ожидаемые результаты описываются в специальном документе. В процессе тестирования ведется журнал испытаний, который затем сравнивается со спецификацией тестов. Желательно, чтобы коллектив разработчиков системы отличался от того, который будет определять процедуры испытаний и проводить их.

При тестировании систем реального времени существует дополнительная сложность из-за большого количества возможных взаимосвязей между задачами. Вероят­ность новой ошибки при исправлении старой очень велика — имеющий опыт разработки программ размером свыше 10 000 строк дает вероятность в пределах от 15 до 50%.

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

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

В многозадачных системах программные модули вначале тестируются отдельно Во время такого тестирования должно быть проверено, что каждая строка програм­мы выполняется хотя бы один раз. Иными словами, если программа содержит коман­ды ветвления типа "if..then..else", то тестовые данные должны обеспечить выполне­ние обеих ветвей.

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

Только после того как все модули были проверены по отдельности и все обнару­женные ошибки исправлены, можно приступать к параллельному исполнению для отладки взаимодействия. Многочисленные взаимосвязи программных модулей мо­гут привести к ошибкам в системе, даже если отдельные модули работают правильно. Общая работа системы — время обработки прерываний, производительность при разной нагрузке — проверяется на основе тестовой спецификации. Особое внимание следует обратить на функции, обеспечивающие надежность и безопасность системы.

Если система включает в себя обработку прерываний и исключений, то необходимо проверить корректность соответствующей реакции. Имитация ошибочных ситуаций позволяет оценить их последствия для системы и ее поведение в этом случае.

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