Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Языки программирования. Практический сравнитель...doc
Скачиваний:
54
Добавлен:
09.09.2019
Размер:
2.68 Mб
Скачать

12.9. Упражнения

1. Изучите следующую попытку решать проблему взаимного исключения в рамках модели с разделяемой памятью, где В1 и В2 — глобальные бу­левы переменные с начальным значением «ложь»:

task body T1 is

Ada

begin

loop

B1 :=True;

loop

exit when not B2;

B1 := False;

B1 :=True;

end loop;

Critical_Section;

B1 := False;

Non_Critical_Section;

end loop;

end T1;

task body T2 is

begin

loop

B2 := True;

loop

exit when not B1;

B2 := False;

B2 := True;

end loop;

Critical_Section;

B2 := False:

Non_Critical_Section;

end loop;

end T2;

Каков смысл переменных В1 и В2? Могут ли обе задачи находиться в своих критических областях в какой-нибудь момент времени? Может ли программа блокироваться? Достигнута ли жизнеспособность?

2. Проверьте решение проблемы взаимного исключения с помощью семафора. Покажите, что во всех чередованиях команд в любой момент времени в критической области может находиться не более одной зада­чи. Что можно сказать относительно взаимоблокировки, жизнеспособ­ности и справедливости?

3. Что произойдет с решением проблемы взаимного исключения, если се­мафору задать начальное значение больше 1?

4. Попробуйте точно определить справедливость. Какая связь между справедливостью и приоритетом?

5. Как бы вы реализовали семафор?

6. Как диспетчер работ Linda обеспечивает, чтобы конкретная работа попадала на конкретный компьютер?

7. Напишите Linda-программу для умножения матриц. Получение каждого векторного произведения считайте отдельной «работой»; на­чальный процесс диспетчеризации заполняет кортежную область «ра­ботами»; рабочие процессы удаляют «работы» и возвращают результа­ты; заключительный процесс сбора удаляет и выводит результаты.

8. Переведите Linda-программу умножения матриц на язык Ada. Решите проблему дважды: один раз с отдельными задачами для диспетчера и сборщика и один раз в рамках единой задачи, которая выполняет обе функции в одном select-операторе.

4Программирование

больших

систем

Глава 13

Декомпозиция программ

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

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

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

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

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