Федеральное агентство по образованию
Государственное образовательное учреждение высшего образования
Уфимский государственный авиационный технический университет
Кафедра автоматизированных систем управления
ЛАБОРАТОРНЫЙ ПрАКТИКУМ
по дисциплине
«Проектирование систем реального времени»
Уфа 2016
Составитель: Сулейманова А.М.
Лабораторный практикум по дисциплине «Проектирование систем реального времени» для студентов специальности 09.05.01 «Применение и эксплуатация автоматизированных систем специального назначения» / Уфимск. гос. авиац. техн. ун-т; сост.: А. М. Сулейманова. – Уфа: Уфимск. гос. авиац. техн. ун-т, 2016. – 42 с.
Цель практикума – помочь студентам в UML проектировании при изучении курса «Проектирование систем реального времени». Закрепить знания, умения и навыки и сформировать компетенции по результатам изучения дисциплины.
Предназначены для студентов, обучающихся по специальности 09.05.01 «Применение и эксплуатация автоматизированных систем специального назначения».
СОДЕРЖАНИЕ
ВВЕДЕНИЕ
|
3
|
ЛАБОРАТОРНАЯ РАБОТА 1
|
3
|
ЛАБОРАТОРНАЯ РАБОТА 2
|
12
|
ЛАБОРАТОРНАЯ РАБОТА 3
|
17
|
ЛАБОРАТОРНАЯ РАБОТА 4
|
24
|
ЛАБОРАТОРНЫЕ РАБОТЫ 5-8
|
38
|
ВВЕДЕНИЕ
Учебный план по специальности 09.05.01 «Применение и эксплуатация автоматизированных систем специального назначения» предполагает изучение на четвертом курсе дисциплины «Проектирование систем реального времени» и лабораторные работы в объеме 32 часов.
Тематика лабораторных работ связана с UML проектированием. Выбор UML методов для проектирования связан со стандартной нотацией для проектирования. Объединение концепций объектно-ориентированного проектирования с концепциями параллельного выполнения необходимо для успешного создания распределенных приложений, работающих в реальном масштабе времени.
Лабораторные работы направлены на закрепление знаний и получение навыков проектирования.
В ходе изучения курса студенты получат возможность закрепить знания и навыки по некоторым смежным дисциплинам. Знания и умения, полученные в ходе лабораторных работ по дисциплине «Проектирование систем реального времени», могут быть использованы в ходе выполнения курсовой работы, а также при изучении последующих дисциплин.
ЛАБОРАТОРНАЯ РАБОТА 1
Процессы и нити. Обработка прерываний. Работа в среде программирования Java.
1. Цель работы.
Целью лабораторной работы является закрепление теоретических знаний о работе задач в операционных системах, а также работы параллельных задач.
2. Задачи.
К задачам лабораторной работы относятся:
Приобретение навыков обработки прерываний;
Изучение возможностей Java для параллельной работы задач и их синхронизации.
3. Теоретическая часть.
Исключительные ситуации
Исключительная ситуация - эта ошибка, которая возникает в результате выполнения программы. Исключение в Jаvа - эта объект, который описывает исключительную ситуацию (ошибку).
При возникновении исключительной ситуации в процессе выполнения программы автоматически создается объект, описывающий эту исключительную ситуацию. Этот объект передается для обработки методу, в котором возникла исключительная ситуация. Говорят, что исключение выбрасывается в метод. По получении объекта исключения метод мажет обработать его или передать для обработки дальше (куда именно - другой вопрос).
Ранее было сказано, что исключения (объекты, описывающие исключительные ситуации) генерируются автоматически, однако их также можно генерировать «вручную», то есть специальными программными методами. На первый взгляд, такая возможность кажется лишней и ненужной, но это не так. Дальше мы увидим, что механизм обработки исключительных ситуаций, в том числе искусственное генерирование исключений, нередко позволяет сделать программный код более компактным и, если хотите, элегантным, значительно упрощая решение сложных, на первый взгляд, задач.
Для того чтобы метод мог обработать исключительную ситуацию, необходимо предусмотреть программный код обработки этой ситуации - на случай ее возникновения. Во-первых, нужно выделить фрагмент кода, который должен контролироваться на предмет генерирования исключительной ситуации. Во-вторых, необходимо создать программный код, непосредственно обрабатывающий исключительную ситуацию, то есть код, который выполняется в случае возникновения исключительной ситуации.
В Java для обработки исключительных ситуаций используется блок try-catch finally. В блок try помещается программный код, который отслеживается на случай, если возникнет исключительная ситуация. Если исключительная ситуация возникает, то управление передается блоку catch. Программный код в этом блоке выполняется, только если возникает исключительная ситуация, причем не любая, а определенного типа. Аргумент, определяющий, какого типа исключительные ситуации обрабатываются в блоке catch, указывается после ключевого слова catch в круглых скобках, то есть в том же формате, что и аргумент метода.
Поскольку в блоке try могут возникать исключения разных типов, для каждого из них можно предусмотреть свой блок catch. Если блоков catch несколько, при возникновении исключительной ситуации они перебираются последовательно до совпадения типа исключительной ситуации с аргументом блока catch.
После блоков try и catch можно указать блок finally с кодом, который выполняется в любом случае вне зависимости от того, возникла исключительная ситуация или нет.
Общая схема использования блока try-catch-finally для обработки исключительных ситуаций выглядит так:
try{
// код, который генерирует исключение
}
саtсh(Тип_исключения_1 объект){
// код для обработки исключения
}
саtсh(Тип_исключения_2 объект){
// код для обработки исключения
}
finally{
// код, который выполняется обязательно
}
Если при исполнении программного кода в блоке try{} ошибок не возникает, после выполнения этого блока выполняется блок finally (если он имеется), затем управление передается следующей после конструкции try-catch-finally команде.
При возникновении ошибки в процессе выполнения кода в блоке try выполнение кода в этом блоке останавливается и начинается поиск подходящего блока catch. Если подходящий блок найден, выполняется его программный код, после чего выполняется код блока finally (при наличии такого). На этом все - далее выполняется код, следующий после блока try-catch-finally.
Может случиться, что в блоке try возникла ошибка, но подходящего блока catch для ее обработки нет. В этом случае исключение выбрасывается из метода и должно быть обработано внешним к методу программным кодом. Согласно правилам языка Java, исключения, которые не обрабатываются в методе и выбрасываются из метода, указываются в сигнатуре метода после ключевого слова throws. То есть указываются классы выбрасываемых из метода исключений. Правда, далеко не все классы выбрасываемых исключений нужно указывать – только так называемые неконтролируемые исключения. Мы рассмотрим их позже.
Если возникает ошибка, обработка которой в программе не предусмотрена, используется обработчик исключительной ситуации по умолчанию. Самое трагическое последствие вызова обработчика по умолчанию состоит в том, что программа завершает работу.
Есть еще одно ключевое слово, которое достаточно часто используется при обработке исключительных ситуаций, а точнее, при генерировании исключительной ситуации. Это ключевое слово throw.
Классы исключений
В Java существует целая иерархия классов, предназначенных для обработки исключительных ситуаций. В вершине этой иерархии находится суперкласс Throwable. У этого суперкласса есть два подкласса: Exception и Error. К классу Error относятся «катастрофические» ошибки, которые невозможно обработать в программе, например переполнение стека памяти. У класса Exception есть подкласс RuntimeException. К классу RuntimeException относятся ошибки времени выполнения программы, которые перехватываются программами пользователя. Исключения для класса RuntimeException определяются автоматически. К ним относятся, например, деление на ноль, выход за пределы массива (недопустимая индексация массива).
В листинге 1 приведен пример программы, в которой происходит обработка исключительной ситуации, заключающейся в делении на ноль.
Листинг 1. Обработка ошибки деления на ноль
class ExceptionDemo{
public static void main(String args[]){
int а,b;
// Блок контроля исключительной ситуации:
try{
b=0;
// Деление на ноль:
а= 100/b;
}catch(ArithmeticException е){
// Обработка исключительной ситуации:
Sуstеm.оut.рrintln("Деление на ноль!");
}
Sуstеm.оut.рrintln("Выполнение программы продолжено!");}
}
Что касается алгоритма, реализованного в программе, то он прост и непритязателен. В главном методе объявляются две целочисленные переменные а и b. Переменной b присваивается нулевое значение, а переменной а - некое значение командой а=100/b. Другими словами, без всяких обиняков выполняется деление на-ноль! Поэтому нет никаких сомнений в том, что при выполнении этого кода возникнет ошибка деления на ноль. Если не предусмотреть ее обработки, на команде а=100/b работа программы, фактически, прекратится, поскольку будет вызван обработчик ошибки по умолчанию, который и довершит начатый при делении на ноль декаданс.
Ошибка деления на ноль относится к классу ArithmeticException, который является подклассом класса RuntimeException. Для отслеживания этой ошибки код, который ее вызывает, заключается в блок try, а для обработки ошибки после блока try размещается блок catch. Аргументом в блок catch передается объект е класса ArithmeticException (объект исключения). В данном случае при обработке ошибки напрямую объект исключения е не используется, но в принципе такая ситуация возможна и часто встречается.
Код, выполняемый при обработке исключительной ситуации деления на ноль, состоит всего из одной команды:
Sуstеm.оut.рrintln("Деление на ноль! "))
То есть при делении на ноль на экран выводится сообщение Деление на ноль!. Здесь важно другое - работа программы при этом не завершается. После выполнения блока catch выполняется следующая после этого блока команда Sуstеm.оut.рrirtln("Выполнение программы продолжено!"). В результате мы получаем два сообщения:
Деление на ноль!
Выполнение программы продолжено!
Еще раз отметим, что в данном случае важно то, что после попытки деления на ноль программа продолжает работу.
Описание исключительной ситуации
В классе Throwable переопределяется метод toString(), который, как известно, определен в общем суперклассе Object, причем переопределяется он так, что в качестве результата возвращает строку, описывающую соответствующую ошибку. Напомним, что метод toString() вызывается автоматически, например, при передаче объекта исключения методу println() в качестве аргумента.
Множественный блок catch{}
Как отмечалось в начале, для каждого типа исключений можно предусмотреть свой блок catch для обработки. Блоки размещаются один за другим и им передаются разные аргументы (объекты исключений разных классов) в соответствии с типом обрабатываемой исключительной ситуации.
Вложенные блоки try
Один блок try может размещаться внутри другого блока trу. В этом случае, если во внутреннем блоке try возникает ошибка и этот блок try не содержит блока catch для ее обработки, исключение выбрасывается во внешний блок try и начинается последовательный просмотр его блоков catch на предмет обработки возникшей ошибки.
Может сложиться и более нетривиальная ситуация, например, когда метод, который вызывается в блоке try, сам содержит блок try. Если в блоке try метода возникает ошибка, не обрабатываемая методом, ее перехватывает внешний блок try, в котором вызывается метод.
Вообще же общий принцип обработки ситуаций при сложной схеме включения блоков try состоит в том, что при входе в очередной блок try контексты обрабатываемых этим блоком исключений записываются в стек. При возникновении ошибки этот стек начинает «раскручиватъся» - контексты исключений просматриваются в обратном порядке (то есть последний занесенный в стек контекст исключения просматривается первым).
Выбрасывание исключений методами
Ранее отмечалось, что если метод выбрасывает или может выбросить исключение, которое в методе не обрабатывается, этот факт нужно отразить при описании метода. В сигнатуре метода после ключевого слова throws перечисляются классы исключений, которые может выбрасывать метод. Причина такой предупредительности состоит в том, что внешним методам нужно сообщить, к каким неприятностям следует быть готовым при вызове данного метода. Ранее мы не использовали ключевое слово throws, хотя некоторые методы и выбрасывали исключения. Дело в том, что перечисляются далеко не все выбрасываемые методом исключения. В частности, не нужно явно указывать исключения класса Еrror, а также класса RuntimeException и его подклассов. Рассматривавшиеся ранее исключения как раз относились к подклассам RuntimeExceptiоn.
Общий синтаксис описания метода, выбрасывающего исключения (которые не обрабатываются в методе), выглядит так:
тип_результата имя_метода(аргументы) throws исключение1, исключение2 .... {
// тело метода
}
Контролируемые и неконтролируемые исключения
Встроенные исключения в Jаvа делятся на контролируемые и неконтролируемые. Фактически, перечислять выбрасываемые методом исключения в сигнатуре метода нужно только в том случае, если они неконтролируемые. В табл.1 приведены некоторые контролируемые исключения в Jаvа.
Таблица 1. Контролируемые исключения в Java
|