Файл: Debian Таненбаум Бос.pdf

ВУЗ: Не указан

Категория: Книга

Дисциплина: Операционные системы

Добавлен: 29.10.2018

Просмотров: 47965

Скачиваний: 190

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

1096  

 Глава 12. Разработка операционных систем 

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

Принцип локальности применим и для файлов. Когда процесс выбирает конкретный 
рабочий каталог, многие из его последующих файловых обращений, скорее всего, будут 
относиться к файлам, расположенным в этом каталоге. Производительность можно 
повысить, если поместить все файлы каталога и их i-узлы близко друг к другу на дис-
ке. Именно этот принцип лежит в основе файловой системы Berkeley Fast File System 
(McKusick et al., 1984).

Другой областью, в которой локальность играет важную роль, является планирование 
потоков в мультипроцессорах. Как было показано в главе 8, один из методов планиро-
вания потоков заключается в том, чтобы попытаться запустить каждый поток на том 
центральном процессоре, на котором он работал в прошлый раз, в надежде, что какие-
нибудь из его блоков все еще находятся в кэше.

12.4.7. Оптимизируйте общий случай

Часто  бывает полезно различать наиболее частый случай и наименее вероятный случай 
и обращаться с ними по-разному. Обычно различные случаи обрабатываются разными 
программами. Важно, чтобы частый случай работал быстро. От алгоритма для редко 
встречающегося случая достаточно добиться корректной работы.

В качестве первого примера рассмотрим вхождение в критическую область. В боль-
шинстве случаев процессу будет удаваться вход в критическую область, особен-
но если внутри этой области процессы проводят не много времени. Операцион-
ная система Windows 8 использует это преимущество, предоставляя вызов WinAPI 
EnterCriticalSection, который является атомарной функцией, проверяющей флаг в режи-
ме пользователя (с помощью команды процессора TSL или ее эквивалента). Если тест 
проходит успешно, процесс просто входит в критическую область, для чего не требуется 
обращения к ядру. Если же результат проверки отрицательный, библиотечная про-
цедура выполняет на семафоре операцию down, чтобы заблокировать процесс. Таким 
образом, если все нормально, обращения к ядру не требуется. В главе 2 мы видели, что 
фьютексы в Linux также оптимизированы для общего случая отсутствия конкуренции.

В качестве второго примера рассмотрим установку будильника, использующего сигна-
лы UNIX. Если в текущий момент ни один будильник не заведен, то просто создается 
запись и помещается в очередь таймеров. Однако если будильник уже заведен, его сле-
дует найти и удалить из очереди таймера. Так как системный вызов alarm не указывает, 
установлен ли уже будильник, система должна предполагать худшее, то есть что он 
уже заведен. Однако в большинстве случаев будильник не будет заведен, и поскольку 
удаление существующего будильника представляет собой дорогое удовольствие, то 
следует различать эти два случая.

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


background image

12.5. Управление проектом   

1097

следует по простому пути (просто добавляется новая очередь таймера без какой-либо 
проверки). Если бит установлен, то очередь таймера требует проверки.

12.5. Управление проектом

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

12.5.1. Мифический человеко-месяц

В  своей классической книге «The Mythical Man Month» Фред Брукс, один из раз-
работчиков системы OS/360, занявшийся впоследствии научной деятельностью, 
рассматривает вопрос, почему так трудно построить большую операционную систему 
(Brooks, 1975, 1995). Когда большинство программистов встречают с его утверждение, 
что специалисты, работающие над большими проектами, могут за год произвести всего 
лишь 1000 строк отлаженного кода, они удивляются, не прилетел ли профессор Брукс 
из космоса, с планеты Баг. Ведь большинство из них помнят, как они создавали про-
грамму из 1000 строк всего за одну ночь. Как же этот объем исходного текста может 
составлять годовую норму для любого программиста, чей IQ превышает 50?

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

 

 1/3 — планирование;

 

 1/6 — кодирование;

 

 1/4 — тестирование модулей;

 

 1/4 — тестирование системы.

Другими словами, собственно написание программы представляет собой самую про-
стую часть проекта. Самым сложным оказывается решить, какими должны быть мо-
дули, а также заставить эти модули корректно общаться друг с другом. В небольшой 
программе, создаваемой одним программистом, планирование составляет как раз 
наиболее легкую часть.

Заголовком книги Брукс обращает внимание читателя на собственное утверждение 
о том, что люди и время не взаимозаменяемы. Такой единицы, как человеко-месяц, 


background image

1098  

 Глава 12. Разработка операционных систем 

в программировании не существует. Если в проекте участвуют 15 человек и на всю 
работу у них уходит 2 года, отсюда не следует, что 360 человек справятся с этой работой 
за один месяц и вряд ли 60 человек выполнят ее за 6 месяцев.

У этого явления есть три причины. Во-первых, работа не может быть полностью 
разделена. До тех пор пока не будет закончено планирование и не будет определено, 
какие модули нужны, а также какими будут интерфейсы, никакое программирование 
не может даже начаться. При двухлетнем проекте одно лишь планирование может за-
нять 8 месяцев.

Во-вторых, чтобы полностью использовать большое число программистов, работу 
следует разделить на большое количество модулей, чтобы всех обеспечить работой. 
Поскольку потенциально каждый модуль взаимодействует с каждым модулем, число 
рассматриваемых пар «модуль — модуль» растет пропорционально квадрату от числа 
модулей, то есть квадрату числа программистов. Поэтому большие проекты с увели-
чением числа программистов очень быстро выходят из-под контроля. Тщательные из-
мерения 63 программных проектов подтвердили, что зависимость времени выполнения 
проекта от количества программистов далеко не так проста, как можно предположить, 
исходя из концепции человеко-месяцев (Boehm, 1981).

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

Брукс подводит итоги своего опыта знакомства с большими проектами, формулируя 
следующий закон (закон Брукса): «Добавление к программному проекту на поздней 
стадии дополнительных людских сил приводит к увеличению сроков выполнения про-
екта
».

Недостаток введения в проект новых людей состоит в том, что их необходимо обучать, 
модули нужно делить заново, чтобы их число соответствовало числу программистов, 
требуется провести множество собраний, чтобы скоординировать работу отдельных 
групп и программистов, и т. д. Абдель-Хамид и Медник (Abdel-Hamid and Madnick, 
1991) получили экспериментальное подтверждение этого закона. Слегка фривольный 
вариант закона Брукса звучит так: «Если собрать девять беременных женщин в одной 
комнате, то они не родят через один месяц
».

12.5.2. Структура команды

Коммерческие  операционные системы представляют собой большие программные 
проекты, которые требуют участия в работе больших команд разработчиков. Уровень 
программистов имеет чрезвычайно большое значение. Уже десятки лет известно, что 
сильнейшие программисты в десять раз продуктивнее плохих программистов (Sackman 
et al., 1968). Неприятность заключается в том, что когда вам нужны 200 программистов, 
сложно найти 200 программистов высочайшей квалификации. Вам придется согласить-
ся на команду, состоящую из программистов самого разного уровня.

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


background image

12.5. Управление проектом   

1099

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

В 1970-е годы Харлан Миллс попытался объединить наблюдения о различиях в уров-
нях квалификации программистов с необходимостью архитектурного соответствия 
и ввел понятие команды главного программиста  (Baker, 1972). Его идея заключалась 
в том, чтобы организовать программистов в нечто подобное хирургической группе 
в противоположность бригаде забойщиков свиней. В отличие от последней команды, 
в которой у каждого работника по ножу и он рубит им направо и налево как сумасшед-
ший, в хирургической группе только один хирург держит в руке скальпель. Остальные 
члены группы лишь ассистируют ему. Предложенная Миллсом структура команды из 
10 разработчиков показана в табл. 12.2.

Таблица 12.2. Предложенная Миллсом структура команды из 10 разработчиков

Должность

Обязанности

Главный программист

Занимается архитектурным дизайном и пишет программу

Второй пилот

Помогает главному программисту и служит резонатором

Администратор

Управляет людьми, бюджетом, пространством, оборудованием, от-
четами и т. д.

Редактор

Редактирует документацию, которую должен писать главный про-
граммист

Секретари

Администратору и редактору нужны секретари

Архивариус

Следит за состоянием архивов программ и документации

Инструментальщик

Снабжает главного программиста необходимыми инструментами

Тестер

Тестирует программы главного программиста

Эксперт по языкам

(Работает неполный рабочий день.) Может дать главному програм-
мисту совет по языкам программирования

Такая структура команды была предложена 30 лет назад. С тех пор кое-что изменилось 
(так, например, исчезла надобность в консультанте по языкам — язык C проще, чем 
PL/1). Но необходимость в централизованном управлении осталась. По-прежнему 
управлять всей схемой должен всего один человек. Хотя использование компьютеров 
позволяет уменьшить штат помощников, но сама идея все еще остается в силе.

Любой большой проект должен быть организован иерархически. На нижнем уровне 
располагается множество маленьких групп, каждую из которых возглавляет главный 
программист. На следующем уровне группы команд должны координироваться менед-
жером. Как показывает опыт, каждый управляемый менеджером человек обходится 
ему в 10 % рабочего времени, поэтому для каждой группы из 10 команд требуется 
отдельный менеджер. Этими менеджерами также нужно управлять, и так далее до 
вершины дерева.

Брукс отмечает, что плохие новости плохо распространяются вверх по дереву. Джерри 
Зальтцер из Массачусетского технологического института назвал этот эффект диодом 
плохих новостей 

. Ни один программист или менеджер не хочет сообщать своему бос-


background image

1100  

 Глава 12. Разработка операционных систем 

су, что проект на 4 месяца отстает от графика и не имеет шансов быть выполненным 
в срок, из-за тысячелетней традиции отрубания головы посланнику, принесшему дур-
ную новость. В результате старший менеджер, как правило, не имеет никакого пред-
ставления о состоянии проекта. Когда становится совершенно очевидно, что в срок 
проект выполнен быть не может ни при каких условиях, старший менеджер нанимает 
дополнительных людей, после чего в действие вступает закон Брукса.

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

Ни Брукс, ни Миллс не могли предвидеть такого роста производства открытых про-
граммных средств. Хотя многие сомневаются (особенно те, кто возглавляет крупные 
компании по разработке программного обеспечения), программы с открытым кодом 
пользуются огромным успехом. Они применяются повсюду, от больших серверов до 
встроенных устройств и от промышленных систем управления до смартфонов. Такие 
крупные компании, как Google и IBM, теперь прикладывают значительные силы 
к совершенствованию операционной системы Linux и вносят немалый вклад в ее код. 
Следует заметить, что наиболее удачные проекты открытых программных средств, 
несомненно, использовали модель главного программиста, то есть всем проектом 
управлял один человек (например, Линус Торвальдс, руководивший разработкой ядра 
операционной системы Linux, и Ричард Столман, направлявший процесс создания 
компилятора GNU C).

12.5.3. Роль опыта

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

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

Неполные знания опасны. В своей книге Брукс описывает явление, названное им эф-
фектом второй системы 

. Часто первый продукт, созданный группой разработчиков, 

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