Введение в, программирование, язык программирования, основы, операционная система
учебники, программирование, основы, введение в,

 

UNIX как операционная среда

Итак, мы описали два во многом противоположных способа построения человеко-машинных систем: процедурный (клиентский) и проективный (администраторский). Если вспомнить, что в процедурных системах ставка делается на немедленное освоение предлагаемого набора решений, становится очевидным некий зазор, в который проваливаются все попытки изучать такую систему: про нее либо "все понятно" (интуитивно), и всякое изучение сведется к перечислению функций (как в инструкции к сотовому телефону), либо "ничего понимать и не надо", и изучать ее может только профессиональный разработчик систем, а пользователю это ничем не поможет.
Так что оставим процедурный подход в стороне и займемся системами проективными. С ними дело обстоит иначе: они как раз требуют изучения; информационная (отчасти даже дидактическая) поддержка - неотъемлемая их часть, и без этого с ними работать невозможно. В качестве примера проективной системы возьмем операционную систему UNIX (см. в лекции первый абзац, посвященный этим четырем символам) со всеми достоинствами и недостатками, из ее проективности проистекающими. Мы будем рассматривать UNIX в первую очередь с точки зрения пользователя, т. е. изучать, что представляет собой UNIX как операционная среда.
Истоки UNIX
Начать все же стоит не с описания системы, а с истории - с зарождения UNIX (см. http://www.bell-labs.com/history). Дело было в конце 60-х, когда вся патриотическая общественность Соединенных Штатов была решительно настроена догнать и перегнать СССР в области вычислительной техники. С этой целью государственные и военные структуры США вкладывали немалые деньги в наукоемкие проекты: разработку новых вычислительных систем, средств хранения и передачи данных.
Программное наполнение нового компьютера - операционная система - считалось тогда неотъемлемой частью именно этого компьютера и разрабатывалось по той же схеме, что и, допустим, стойка для размещения всех его узлов. Группа разработчиков получала в руки "железо" с описанием его архитектуры и задание: сделать так, чтобы можно было решать определенные задачи. Если программистам что-то не нравилось, в стенд вносились аппаратные изменения, и работа начиналась заново. Задач было много, и совокупность их решений называлась operation system, то есть система правил работы с машиной.
Star Trek
Разработкой такой системы занималась тогда исследовательская лаборатория Bell Labs, подразделение американской телефонной корпорации AT&T. Средства "холодной войны" позволили привлекать к этому делу людей весьма сведущих (с высшим образованием как минимум), в том числе из такого солидного научного центра, как Массачусетский технологический институт (MIT). Полным ходом шли исследования и эксперименты над составными частями некой универсальной системы (она называлась Multics) с разделением времени, взаимодействием между компьютерами, секретностью доступа к данным и т. п. Multics дожила до создания работающего стенда и потихоньку скончалась: изготовление второго стенда (не говоря уж о тиражировании) обошлось бы так дорого, что заказчики решили не платить вовсе.
Небольшая группа исследователей, главным образом Кен Томпсон (Ken Thompson) и Деннис Ричи (Dennis Ritchie), продолжала искать новые пути. Изредка они составляли проекты исследований, которые в Bell Labs поддерживали, за исключением того, что вычислительную машину на эти проекты не выделяли. Машинное время на ЭВМ из-под Multics стоило очень дорого, к тому же неугомонный Кен хотел отлаживать написанную им компьютерную игру Star Trek (в упомянутой статье AT&T ее пришлось переименовать в Space Travel: цензура XXI века - авторское право - не позволяет публично использовать название культового телесериала) и играть в нее. Довольно быстро где-то в подвалах AT&T отыскалась слабо загруженная работой машина PDP-7, на которую первым делом была перенесена игра.
К пуговице Кена и Денниса пришлось пришить приличные брюки: разработать хорошо сбалансированную модель псевдопараллелизма (чтобы играть, используя графические устройства ввода/вывода, и тут же редактировать и отлаживать программу на текстовом), алгоритмы разделения памяти, эффективную систему хранения данных на жестком диске (файловую систему), текстовый редактор, командный интерпретатор и многое другое. Активно участвующий в работе группы Брайан Керниган (Brian Kernigan) придумал системе имя - UNIX. Имя получилось звучное (особенно приятное жителю United States of America или United Kingdom) и содержало легкий кивок (или пинок?) в сторону почившего Multics.
Идеология
Директор исследовательского центра, Дуг Макилрой (Doug McIlroy), специалист в области макроязыков, навел Кена на идею канала (pipe) между командами системы. Каналы сыграли очень важную роль в формировании идеологии UNIX как инструмента. Каждая программа (utility) должна решать одну простую задачу, но решать хорошо. Данные должны передаваться в текстовом виде, тогда и человек сможет в них разобраться, и для самих программ установится общий, но гибкий формат взаимодействия. Решение сложных задач - совместная работа нескольких программ, передающих друг другу данные по каналам. Этим взаимодействием управляет оболочка (shell), предназначенная для интеграции программ и управления ими.
В начале 70-х UNIX уже твердо стоял на ногах: имелась и новая машина (PDP-11), и заказчик (патентное бюро Bell Labs). Перенос системы, написанной на автокоде, с одной архитектуры на другую был довольно непрост, и Керниган предложил переписать ее на высокоуровневом языке программирования, не зависящем от конкретной реализации. Томпсон попытался использовать Фортран, но этот язык не годился для системного программирования. Тогда он написал собственный язык программирования, B, который в некоторых местах получился слишком низкоуровневым. Деннис основательно переработал B - и на свет появился C (Си), который и по сей день используется для написания операционных систем.
Разработчики UNIX System Group (USG) исправляли и дополняли систему сообща. Идея и первоначальная реализация какой-нибудь утилиты могла принадлежать одному человеку, но доводить ее до совершенства мог любой. Кроме доступа к исходным текстам, совместная работа требовала, чтобы все идеи и все готовые возможности системы были задокументированы. Макилрой отлично знал: если утилита внятно и грамотно описана на родном языке, то она и хорошо запрограммирована, и пользоваться ею будет удобно. Вдобавок UNIX-сообщество росло: к середине 70-х многие университеты США уже использовали новую систему. Если нельзя сию минуту пойти и спросить автора, что делает его программа и как ею пользоваться, значит, нужно прочесть об этом в документации. Ричи предложил использовать формат, разработанный для патентного бюро, а Макилрой усовершенствовал программу документирования и создал концепцию страницы руководства (manual page), введя в документ обязательные тематические параграфы и ссылки.
К середине 70-х Bell Labs уже активно торговала UNIX, что не замедлило сказаться на темпах и направлении развития системы. С одной стороны, получая обратную связь от пользователей, эксплуатирующих систему на производстве, разработчики получили возможность избавляться от множества мелких ошибок, неизбежно таящихся в системе. Но с другой стороны, научные исследования в рамках UNIX становились все более и более ограниченными: любое экспериментальное архитектурное изменение повлекло бы за собой несовместимость с предыдущими выпусками системы (а то и неработоспособность отдельных ее частей) и, как следствие, гнев заказчиков и падение продаж. Поэтому центры развития UNIX переместились в университеты, и без того использующие эту систему в академических целях.
BSD
Одним из главных центров стал Университет Беркли, Калифорния. Три факультета - компьютерный, математический и статистический - использовали UNIX с момента появления академической лицензии. В середине 70-х, когда движение UNIX стало замедляться по описанным выше причинам, выяснилось, что множество наработок для UNIX выходят за рамки AT&T (и не подчиняются их политике лицензирования). Поэтому в Беркли стали готовить свой выпуск UNIX со всевозможными накопившимися изменениями и дополнениями - Berkeley Software Distribution (BSD). Это стало возможным после того, как Кен Томпсон провел в Беркли полгода, обучая энтузиастов премудростям работы с UNIX.
Любой человек, каким-то образом получивший копию BSD (которая распространялась обязательно с приложением исходных текстов), считался собственником этой копии и мог, в свою очередь, копировать ее и передавать кому угодно. В Беркли рассуждали так: чем самим исправлять все ошибки, лучше дать возможность сделать это пользователю. Если при этом он окажется достаточно грамотен и улучшит работу системы - уже неплохо, а если его доработки можно будет использовать в следующем выпуске системы - совсем хорошо. Кроме того, такая лицензия существенно облегчала и организацию исследовательских работ, и промышленную эксплуатацию систем BSD.
Многое из того, что по сей день входит в состав операционных систем (даже совсем не UNIX) написано в конце 70-х и в 80-е годы в Беркли или для Беркли. Реализация сетевых протоколов TCP/IP (на которой основывается работа Internet) - проект, выполненный по заказу DARPA (военного ведомства) - считается на сегодня самой надежной и работоспособной.
Гнезда UNIX
Все современные UNIX-системы можно отнести либо к гнезду USG (это прямые наследники творения Bell Labs: UnixWare, SCO Open Server, HPUX, AIX, Solaris), либо к гнезду BSD (все системы, название которых включает BSD, ядро Mac OS - Darwin, Tru64 и некоторые другие). (Полную диаграмму наследования выпусков разных UNIX-систем можно найти на http://www.levenez.com/unix.) Особняком стоят столь популярные сегодня системы с общим именем Linux. Строго говоря, они не наследуют ничего, кроме идей, хотя по архитектурным особенностям традиционно относятся к гнезду USG. Стоит добавить, что гнездо USG еще называют System V или SYSV, по имени самого успешного творения Bеll Labs, выпущенного в середине 80-х.
Следует понимать, что Linux - название даже не операционной системы, а одного только ядра. Ядро это, ориентированное первоначально на i386, написал в одиночку Линус Торвальдс (Linus Torvalds), желая создать на этом, тогда еще маломощном, компьютере среду выполнения UNIX, аналогичную коммерческим версиям. Тогда, в самом начале 90-х, UNIX-подобные системы для i386 были неполными и довольно нелепыми, а кроме того, исходные тексты этих систем не были доступны. Сам автор превосходно описывает процесс создания ядра в книге "Just for Fun", что можно перевести как "Из любви к искусству" или "Забавы ради"). Все остальное в Linux-системе - программы, написанные программистами со всего мира и собранные (после тщательной доработки напильником) в единое целое авторами дистрибутива.
Благодаря Internet (а в конечном счете - UNIX) в разработке открытых UNIX-систем может участвовать любой. Открытых ОС на сегодня насчитывается несколько десятков: помимо разнообразных дистрибутивов Linux, существует несколько открытых BSD-систем (самые известные - FreeBSD, OpenBSD и NetBSD), микроядерная система GNU HURD и множество других, подчас самых экзотических (есть даже проект FreeDOS, воссоздающий свойства DOS). Вокруг каждой системы образуется многонациональное сообщество (community) заинтересованных в ее развитии людей. Поддержка сообществом подстегнула развитие открытых UNIX-систем: стало проще искать новые области применения систем, привлекать новые источники финансирования, исправлять ошибки и т. д.
Открытость исходных текстов позволяет задействовать один и тот же программный продукт в любой системе. Это создает свободный рынок вычислительных систем: выбор пользователя диктуется спецификой системы, формой поддержки, ее гибкостью и прочими значимыми свойствами, а не одним только тем, что в выбранной системе (и только в ней) есть какая-то особая программа, к которой пользователя приучили предыдущие выпуски этой же системы.
Из всей UNIX-истории нам важны два факта. Во-первых, UNIX создавался для того, чтобы на нем немедленно работать, а не для того, чтобы им потом торговать, т. е. для себя. Это значит, что стадия отчуждения (в понимании, скажем, Маркса) системы как продукта какое-то время для UNIX вовсе не существовала. А когда им додумались торговать, уже ничего испортить, перекроив удобство в привлекательность, было нельзя. Образ мысли авторов UNIX, людей с университетским образованием, породил особую идеологию системы, в духе бэконовского "знание - сила". Нетрудно проследить, как это отразилось на принципах формирования системы, которые сами разработчики, наверное, не всегда и объявляли, но которых почти всегда придерживались. Именно попытка формализовать и обосновать эти принципы и привела к понятию "проективной системы".

Структура UNIX

Рассмотрим теперь вкратце общее устройство UNIX как операционной среды (более подробное описание архитектуры операционной системы UNIX.

Ядро

Центром ОС является, как было сказано, менеджер ресурсов и планировщик задач. Функции этих частей системы востребованы, пока есть хоть одна задача (т. е. всегда), и к тому же работают в режиме супервизора. В UNIX они составляют ядро системы (kernel). Ядро постоянно находится в памяти, обслуживая непрерывный поток запросов на использование универсальных ресурсов системы: памяти и времени. В ядро UNIX, кроме того, входит реализация сетевых протоколов (были попытки выделить стек протоколов TCP/IP в отдельный модуль, но это многократно снижает производительность, поскольку реализация некоторых особенностей TCP/IP, как ни странно, требует жесткой привязки к внешним устройствам и структурам ядра). Ядро UNIX предоставляет программам пользователя унифицированный интерфейс к ресурсам компьютера (так называемые системные вызовы, system calls) и содержит всю непростую логику распределения ресурсов по задачам, которые в UNIX называются процессами.
На самом деле далеко не все, что работает в режиме ядра (супервизора), обязано присутствовать в конкретной системе, запущенной на конкретном компьютере. Функции, отвечающие за работу с самыми разнообразными внешними устройствами (которые отличаются логикой работы), бессмысленно включать в ядро все сразу. Отдельно взятый компьютер не содержит и сотой части всех устройств, поддерживаемых системой. Более того, зачастую весьма трудно автоматически определить марку устройства, подключенного к системе; еще труднее, не имея обширнейшей базы данных по всем устройствам, определить, какому из известных устройств соответствует найденное системой неизвестное, и вообще соответствует ли (т. е. можно ли с ним работать как с несколько иным, но известным). А вот администратору системы достаточно для этого посмотреть маркировку на самой плате или почитать документацию. Так мы приходим к понятию драйвера устройства ("драйвер" по-английски будет handler, а слово driver используется для обозначения устройства, которое что-нибудь крутит или тащит, например лентопротяжного. Однако пишущие по-английски носители других языков часто говорят driver вместо handler... Путаница неизбежна, если не вникать каждый раз в то, о чем речь). Драйверы включаются в состав ядра, если соответствующие им устройства входят (или могут входить) в состав компьютера. Одни драйверы (скажем, шины PCI) есть в системе почти всегда, другие написаны специально для контроллера какого-нибудь экзотического устройства. Существуют драйверы, которые не являются интерфейсной частью внешнего устройства, а реализуют дополнительную функциональность самой системы (скажем, драйвер файловой системы ISO9660, которая используется на лазерных дисках).
В старых версиях UNIX (основанных непосредственно на BSD4.3 или UNIX SystemV различных редакций) все драйверы приходилось заранее прикомпоновывать к ядру (т. е. пользоваться компоновщиком ld, таким же, какой применяется при сборке программ). Более того, запуск ld был своеобразной уступкой коммерческих версий UNIX его некоммерческому духу, потому что на самом деле драйверы компилировались из исходных текстов на языке Си, как и все ядро системы (так было, например, в FreeBSD3.* и в Linux до версии 1.2). Процесс компиляции ядра системы из исходных текстов или компоновки его из объектных модулей носит название сборки (пересборки) ядра и во многих системах практикуется и по сей день.
С увеличением размеров оперативной памяти отпала необходимость экономить байты на сборке ядра, в точности соответствующего имеющемуся профилю оборудования. Разработчики стараются собрать ядро, содержащее драйверы всех самых популярных устройств, чтобы оно, не занимая слишком много памяти, могло управлять системой на подавляющем большинстве компьютеров. Такое ядро называется базовым (generic). Поскольку для пересборки ядра необходимы многие знания (как минимум, нужно разбираться в архитектуре используемой версии UNIX, в архитектуре ЭВМ и в особенности внешних устройств ), а нужда в этом может возникнуть при первой же установке системы, хорошо укомплектованное базовое ядро во многом облегчает жизнь неопытному пользователю.

Модули ядра

Если базового ядра все-таки недостаточно, в современных системах многие драйверы можно загружать динамически, из модулей ядра. Ядро, уже работающее в памяти, можно дополнить, загрузив такой модуль из файла специального формата, после чего перекомпоновать ядро на ходу (специальным компоновщиком). В эти модули можно вынести необязательные функциональности системы (например, фильтрацию сетевых пакетов), после чего базовое ядро станет еще меньше, однако процесс загрузки усложнится, так как некоторые из подгружаемых модулей понадобятся ядру уже при старте системы, когда доступа к файлам может и не быть. Типичный пример: для работы с диском ядру нужен драйвер дискового массива (RAID-контроллера), который вместе с программой загрузки и компоновки модулей на этом массиве и находится. Разные системы выходят из этой ситуации по-разному.
Модули ядра работают в режиме ядра, поэтому обращаться с ними следует крайне осторожно: ошибка в таком модуле (скажем, запись неизвестно чего неизвестно куда в память) столь же фатальна, как и ошибка ядра, и в лучшем случае вызовет крах системы (в худшем случае система ее заметит не сразу). Функции модулей с точки зрения ОС совпадают с функциями ядра: организация интерфейса к ресурсам и дополнительная логика работы системы.

Демоны

Прочие части UNIX запускаются уже как процессы в режиме пользователя. С ядром взаимодействуют функциональные подсистемы (службы), то есть наборы программных средств, выполняющих определенную функцию (например, система печати, система передачи почты и т. д.). Управляющий центр функциональной подсистемы - так называемый демон (daemon, в переводах с греческого называемый "даймон"). Как сказано в "Руководстве системного администратора UNIX" (), "Даймон не служит ни злу, ни добру, он только определяет характер и личность человека. Он больше похож на ангела-хранителя...". Наличие рогов и трезубца у демонов BSD еще ни о чем не говорит, например, демона FreeBSD зовут совсем по-человечески - Чак (Chuck). Существо, появляющееся в Linux, хоть и зовется Такс (Tux), не имеет ни рогов, ни трезубца, потому что "по национальности" - пингвин. Демон - это процесс, который запускается при старте UNIX для обслуживания запросов к функциональной подсистеме. Пользователю запускать его незачем, он работает всегда. Именно демон обменивается данными с ядром системы, часто он держит очередь пользовательских запросов, работает с сетью и т. д.

Утилиты

Обращаться к системным вызовам могут, конечно, не только демоны, но и вообще любые программы. В UNIX входит немало программ, при помощи которых можно решать разнообразные инструментальные (т. е. связанные с работой самой системы) задачи. Это так называемые системные утилиты. Они используются в первую очередь самой системой (причем вызываются, как правило, из командных сценариев, о которых рассказывается в лекции 11) и системным администратором - для управления системой. Однако и пользователь, не обладающий правами администратора, вполне может задействовать системные утилиты, если они помогают ему в работе, а системе не мешают (например, создавать файловую систему на дискете, просматривать состояние системы или демонов и т. п.).
Слово "утилиты" (utilities) буквально означает "полезности". Утилиты - это программы, которые могут понадобиться при решении всевозможных задач. Если есть высокая вероятность, что некоторая программа может понадобиться более чем одному пользователю для решения более чем одной задачи, то ее стоит включить в систему. Таких пользовательских утилит в UNIX еще больше, чем системных (чем определенно нарушается принцип У контекста; о том, как устранить это нарушение, речь пойдет в лекции 6). Множество пользовательских утилит занимается преобразованием текста, так как текстовый файл - универсальное пространство для создания умопостижимых моделей. Немало утилит помогает при разработке решений: компиляторы, отладчики, редакторы диаграмм, трассировщики и т. д. Почти всеми пользовательскими утилитами пользуется система, потому что при проективном подходе вообще невозможно провести четкую границу между системным и пользовательским наполнением. К обеим категориям, например, относятся утилиты для работы с файлами и файловой системой или интерпретатор командной строки (shell). На shell написаны все системные сценарии, поскольку он представляет собой еще и удобный высокоуровневый язык программирования.

Программные продукты и пакеты

Понятно, что на всякую прикладную область утилит не напасешься. Чем сложнее и дальше от инструментальной области задача, тем меньше смысла включать инструменты ее решения в систему. Тем не менее, раз уж задача есть, значит, кому-то придется ее решать. Такие специализированные наборы программ хотелось бы иметь если не в самой системе, то где-то "рядом", чтобы, как только появится пользователь со своими задачами, предоставить ему средства их решения. И уж конечно метаинструментарий - средства изготовления таких инструментов - в системе должен быть (метаинструментарий - это средства программирования и вообще разработки программ: языки программирования, общие, интерфейсные и предметно-ориентированные библиотеки, RAD - средства быстрой разработки и т. п.). Такой набор программ для решения прикладных задач называется программным продуктом.
Для того чтобы оперативно добавлять программный продукт в систему или удалять его оттуда, необходимо заранее договориться о размещении в файловой системе всех входящих в него файлов. Запомнив каждый файл с полным именем, мы получим архив, целиком определяющий расположение программного продукта в системе. Такой архив в UNIX называется пакетом. Мы можем устанавливать пакет в систему и удалять его, зная, что записываем и удаляем файлы, принадлежащие только ему. В пакете могут храниться не только программные продукты, но и вообще любые "кирпичики", из которых можно складывать систему: утилиты, драйверы, документация, шрифты и все остальное. Если при установке или удалении пакета нужно проделать какие-нибудь действия (например, зарегистрировать устанавливаемый шрифт), к нему прилагаются установочный сценарий и сценарий удаления.
Система, настроенная на решение определенных задач, не обязательно должна содержать все возможные пакеты. Как правило, в дистрибутив UNIX входит несколько тысяч пакетов разного назначения и объема, от утилиты, сообщающей, в какой фазе сегодня находится луна, до издательской системы. В действительности их устанавливают несколько сотен.


Интерфейс
Для диалога с пользователем в UNIX выбран интерфейс командной строки. О достоинствах и недостатках этого способа общения человека и машины будет сказано далее, пока же ограничимся только его описанием: человек вводит команду с клавиатуры, машина ее выполняет. Команды могут быть совсем короткими (одно нажатие), могут содержать имя запускаемой утилиты и несколько коротких параметров, а могут быть даже небольшими программами (символов в сто). Команды большего размера неудобно вводить и исправлять прямо в командной строке, их стоит складывать в файл, называемый сценарием (script). Такой сценарий тоже считается программой, его можно вызывать по имени, передавать параметры и т. д. Все эти команды распознает и выполняет интерпретатор командной строки (shell, "оболочка"), в который встроены специальные возможности, помогающие очень быстро набирать командную строку и оперативно объединять и использовать результаты выполнения других программ.
Для обозначения точки входа в систему - места, откуда приходят команды, и куда следует выдавать результат их работы, используется понятие терминала. Терминал - это устройство, способное принимать и передавать текстовую информацию. Раньше было великое множество таких устройств, они подключались к последовательному порту компьютера и состояли из клавиатуры и устройства вывода текста (либо принтера, либо так называемого алфавитно-цифрового монитора, т. е. монитора, который умеет выводить буквы, цифры и некоторые символы). Сейчас с этой задачей справляются специальные драйверы.
Способ доступа к файлам на носителе данных и принцип их именования (идентификации) принято называть файловой системой. Файловая система в UNIX - это не только способ хранения собственно файлов, но и вообще место хранения и отображения информации о системе. Манипулировать файлами с помощью соответствующих утилит чрезвычайно легко - и вручную, и автоматически, из командного сценария. Часто пользователь обменивается информацией с UNIX путем изменения или просмотра специальных файлов. Поэтому файловую систему можно считать частью интерфейса UNIX.
Процессы
В роли задач в UNIX выступают процессы. Процесс - это программа, запущенная пользователем, которая находится в памяти и, как полагается задаче, потребляет ресурсы: выполняется, требует памяти, обменивается данными с системой, внешними устройствами и другими процессами. При запуске процесс получает уникальный идентификатор процесса (Process IDentifier, PID), по которому он становится доступен другим процессам и планировщику. Планировщик процессов в UNIX устроен сложнее, чем описано в лекции 4. Наше описание предельно упрощено, а полностью разобраться в планировании процессов поможет . Главное отличие планировщика UNIX заключается в том, что каждая задача из очереди работает в течение всего отведенного ей промежутка времени, только если ей есть чем заняться. Если задача к этому времени работать не может (например, ожидает завершения операции ввода/вывода, или сигнала, или освобождения какого-либо ресурса), она из начала очереди перемещается в конец "очереди для тех, кто без очереди" или очереди "спящих" задач. Как только какая-нибудь задача из очереди спящих просыпается, ей тут же отводится место в начале обычной очереди. Таким образом максимально сокращается время простоя (idle) системы, если, конечно, выполняемых задач достаточно для того, чтобы полностью ее загрузить. Сверх того процессы в UNIX могут иметь разные приоритеты, сообразно которым идет планирование очередного запуска процесса (например, полностью отработав свой промежуток времени, процесс может помещаться не в конец очереди).
Между собой процессы могут обмениваться данными не только стандартными пользовательскими средствами (посредством файлов, каналов или сокетов (о двух последних читайте в, но и с помощью более быстрых системных, именуемых средствами межпроцессного взаимодействия (Interprocess Communication, IPC). Процессы могут заказать у системы общую память (тогда часть адресного пространства каждого будет ссылаться на один и тот же кусок реальной памяти), для индикации занятости ресурса использовать семафор (система гарантирует, что запрошенный ресурс действительно будет свободен, пока процесс не откроет семафор) и посылать друг другу сигналы и сообщения.
Реализация принципов проективной системы
UNIX - несомненно проективная человеко-машинная система. Попробуем из того, что уже сказано о UNIX, выбрать явные отсылки к принципам формирования именно проективных систем. В дальнейшем мы еще не раз будем вспоминать эти принципы, поэтому введем для них соответствующие сокращения.
Принцип информационной открытости (И) соблюдается в UNIX по максимуму. Все, что можно документировать, документируется. Если к какому-то средству документации нет или она недостаточно толковая, такое средство выпадает из системы, им практически невозможно пользоваться. Документация ведется не только на средства (утилиты, системные и библиотечные вызовы), но и на структуру системных файлов, работу с устройствами и многое другое. Подробнее об информационном наполнении UNIX рассказано в лекции 6. Большинство программных продуктов для UNIX и основательная часть базовых дистрибутивов UNIX-подобных систем распространяется в исходных текстах. Это означает, что любому квалифицированному пользователю доступна полная информация о внутреннем устройстве инструмента, которым он пользуется, и любой может исправить или улучшить его по своему усмотрению.
Принцип минимизации затрат (З) последовательно реализован в интерфейсе командной строки. В соответствии с этим принципом пользователь всякий раз решает некую мыслительную задачу, с тем чтобы быстро реализовать ее решение на выбранном им командном языке (чаще всего это shell, но для иных задач полезнее sed или awk, а для задач побольше - perl, python, tcl, ruby и т. п.); при этом дальнейшее использование этого решения можно целиком доверить компьютеру (написать сценарий). Как следует из З, такие решения не всегда можно воспринять "с первого взгляда", их надо "читать", с другой стороны, читать их приходится несравненно реже, чем последовательно писать (прямое построение проекта). В системных текстовых редакторах, о которых речь пойдет в лекциях 15 и 16, принцип З выдержан наиболее последовательно. Большинство демонов и утилит UNIX пользуется для настройки своей работы текстовыми файлами, т. е. управляется проектами.
Принцип умопостижимости контекста (У) включает правило, которому очень тяжело следовать: "7+-2" (см. главу 2). Добавляя в систему из семи элементов еще пять, мы перегружаем контекст. По-хорошему, после этого требуется реструктуризация перегруженного уровня системы, а это может повлечь за собой изменение структуры всей системы (что есть, в сущности, балансировка Б-дерева). Поэтому однотипных частей обычно набирается до дюжины, прежде чем разработчики решаются всерьез заняться реструктуризацией. В UNIX редко встречаются перегруженные неструктурированные инструментарии: если человек создает какой-либо предмет для того, чтобы им пользоваться, он делает его удобным.
Зато другие правила соблюдаются гораздо строже. Практически все демоны и приложения UNIX используют так называемые файлы настроек (или rc-файлы, от resource container). Это текстовые файлы (требование human readable), и, если количество содержащейся в них информации достаточно велико, они разбиты на секции и подсекции, чтобы соблюсти требование human writeable. В самых сложных из них, например в файле настройки Web-сервера Apache, предусмотрена инструкция include, чтобы помещать различные по контексту группы настроек в разные файлы и даже в отдельные каталоги. В текстовом виде хранятся и системные журналы, и документация. Множество средств переработки и фильтрации текстов позволяют создать умопостижимый контекст, разумно ограничивая большие объемы данных и отсекая заведомо ненужное.
Принцип персональной ответственности (О) предполагает, что чем больше человек знает о системе, тем больше у него возможностей влиять на ее поведение. С другой стороны, если человек совершает некоторое действие, значит, он знает, что делает, и берет на себя ответственность за это действие. Примеры с удалением всех файлов, приведенные в лекции 2, взяты именно из UNIX; они наглядно демонстрируют вторую часть этого принципа (правило "захотел - получил"). Вообще, составляя всякий раз команду в shell, пользователь должен быть уверен в ее правильности или по крайней мере безвредности. Команда при этом не обязана быть "значком", т. е. может легко читаться, но не являть собою обозначение какого-то конкретного решения. Стало быть, пользователь-новичок должен перечитывать ее до тех пор, пока не убедится в ее правильности. Но от ответственности ему не уйти.
Первая часть принципа ответственности выражена в UNIX тем, что существует пользователь, которому вообще никакие действия по изменению системы не запрещены! Это так называемый суперпользователь, или root. Как правило, правами суперпользователя наделяют человека настолько опытного, что он в состоянии нести ответственность за любое поведение вверенной ему системы. Он имеет такую возможность в силу соблюдения всех предыдущих принципов: И - у него есть достаточно информации, чтобы разобраться в поведении любой части системы, З - ему не надо часами давить на клавиши, чтобы перенастроить ту ее часть, которая работает недостаточно хорошо, У - сама система организована так, что один человек способен (по крайней мере на уровне проекта) решить любую возникшую задачу.
Инструментарии и стратегия
Набор программных продуктов для UNIX наглядно иллюстрирует первое следствие принципов организации проективной ОС: основное направление развития - инструментарии. В полном дистрибутиве типичной UNIX-системы от шестой до третьей части всего списка пакетов относится к области разработки. Например, на 8268 пакетов в официальном дистрибутиве FreeBSD-5.2 в категории devel (средства разработки), lang (языки программирования) и x11-toolkits (графические инструментарии) входит в общей сложности 1506 пакетов. В ALT Linux Master 2.2 доля библиотек превышает 20%. Стоит заметить, что в специализированные дистрибутивы или в системы, не распространяемые под свободной лицензией, средства разработки могут не входить: в одни - за ненадобностью, в другие - из-за желания авторов заработать на продаже инструментариев.
Как и во всякой проективной системе, в UNIX "велосипедный парк" - весьма обычное явление. Сталкиваясь с задачей "здесь и сейчас", бывает непросто выбрать между самостоятельным поиском решения и изучением способов перестройки чужого. Чтобы понять, насколько имеющийся инструмент поможет в решении задачи, и стоит ли конструировать новый, нужен опыт, который приходит только со временем. По истечении этого времени в гараже каждого пользователя UNIX будет пылиться известное количество велосипедов всевозможной кривизны. Как правило, все эти 10, 50 и 1000-строчные сценарии на shell, sed, awk или perl очень дороги сердцу автора, и он переносит их на каждое новое рабочее место.
Дело еще и в том, что система рассчитана на профессиональное решение даже самой пустяковой задачи. Это значит, что стратегию "исследование - выбор - реализация - решение", описанную нами в лекции 1, стоит применять во всех случаях, даже когда кажется, что можно начать сразу с "решения". В UNIX работа вручную всегда хуже автоматической. Говорят: "Юниксоид за три часа напишет программу, и она за пять секунд сделает работу, на которую вручную ушел бы час". Смех смехом, но любой, кому приходится повторять одни и те же действия в четвертый, пятый, десятый раз, довольно быстро приходит к идее командного сценария.

 

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г.Яндекс.Метрика