Курсовой

Page 1

8 ВВЕДЕНИЕ Операционная система – комплекс управляющих и обрабатывающих программ, которые, с одной стороны, выступают как интерфейс между устройствами вычислительной системы и прикладными программами, а с другой стороны – предназначены для управления устройствами, управления вычислительными процессами, эффективного распределения вычислительных ресурсов между вычислительными процессами и организации надёжных вычислений. Это определение применимо к большинству современных операционных систем общего назначения. В логической структуре типичной вычислительной системы операционная система занимает положение между устройствами с их микроархитектурой, машинным языком и, возможно, собственными (встроенными) микропрограммами – с одной стороны – и прикладными программами с другой. Операционные системы различаются особенностями реализации алгоритмов управления ресурсами компьютера, областями использования. Так, в зависимости от алгоритма управления процессором, операционные системы делятся на следующие виды. 1. Однозадачные и многозадачные. 2. Однопользовательские и многопользовательские. 3. Однопроцессорные и многопроцессорные системы. 4. Локальные и сетевые. По числу одновременно выполняемых задач операционные системы делятся на два класса. 1. Однозадачные (MS DOS). 2. Многозадачные (OS/2, Unix, Windows). В зависимости от областей использования многозадачные ОС подразделяются на три типа. 1. Системы пакетной обработки (ОС ЕС) 2. Системы с разделением времени (Unix, Linux, Windows) 3. Системы реального времени (RT11) Все современные ОС обеспечивают создание файловой системы, которая предназначена для хранения данных на дисках и обеспечения доступа к ним. Основные функции операционной системы:  исполнение запросов программ (ввод и вывод данных, запуск и остановка других программ, выделение и освобождение дополнительной памяти и др.);  загрузка программ в оперативную память и их выполнение.  стандартизованный доступ к периферийным устройствам (устройства ввода-вывода);  управление оперативной памятью (распределение между процессами, организация виртуальной памяти);


9  управление доступом к данным на энергонезависимых носителях (таких как жёсткий диск, оптические диски и др.), организованным в той или иной файловой системе;  обеспечение пользовательского интерфейса;  сохранение информации об ошибках системы; Разработчикам программного обеспечения операционная система позволяет абстрагироваться от деталей реализации и функционирования устройств, предоставляя минимально необходимый набор функций (см.: интерфейс программирования приложений). В большинстве вычислительных систем операционная система является основной, наиболее важной (а иногда и единственной) частью системного программного обеспечения. С 1990-х годов наиболее распространёнными операционными системами являются системы семейства Windows и системы класса UNIX (особенно Linux и Mac OS).


10 1 ПОСТАНОВКА ЗАДАЧИ 1.1 Общая постановка задачи Общая постановка задачи заключается в глубоком изучении предметной области, анализе информационного материала, в соответствии с вариантом задания. А именно: − аппаратная платформа: сети ЭВМ; − особенности управления ресурсами: однозадачная, однопользовательская, многопроцессорная; − особенности областей использования: системы разделения времени, системы реального времени; − организация оперативной памяти: без использования внешней памяти, с переменными разделами; − средства взаимодействия процессоров: семафоры; − управление процессами: квантование времени; − организация файловой системы: UNIX. 1.2 Цель создания курсового проекта Целью создания проекта является приобретение практических навыков проектирования операционных систем и комплексного инженерного проектирования программного обеспечения и демонстрации работы алгоритмов, связанных с управлением ресурсов ЭВМ операционными системами. 1.3 Актуальность разработки и область применения Проектируемая операционная система может быть использована в учебных заведениях в качестве наглядного пособия при обучении приемам и правилам построения интерактивной операционной системы. Также проектируемая гипотетическая операционная система может быть использована для наглядного самообучения и повышения знаний о принципах работы вычислительных и операционных систем.


11 2 ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ 2.1 Сети ЭВМ Сетевая операционная система составляет основу любой вычислительной сети. Каждый компьютер в сети в значительной степени автономен, поэтому под сетевой операционной системой в широком смысле понимается совокупность операционных систем отдельных компьютеров, взаимодействующих с целью обмена сообщениями и разделения ресурсов по единым правилам - протоколам. В узком смысле сетевая ОС - это операционная система отдельного компьютера, обеспечивающая ему возможность работать в сети. В сетевой операционной системе отдельной машины можно выделить несколько частей (см. рис. 2.1). 1. Средства управления локальными ресурсами компьютера: функции распределения оперативной памяти между процессами, планирования и диспетчеризации процессов, управления процессорами в мультипроцессорных машинах, управления периферийными устройствами и другие функции управления ресурсами локальных ОС. 2. Средства предоставления собственных ресурсов и услуг в общее пользование - серверная часть ОС (сервер). Эти средства обеспечивают, например, блокировку файлов и записей, что необходимо для их совместного использования; ведение справочников имен сетевых ресурсов; обработку запросов удаленного доступа к собственной файловой системе и базе данных; управление очередями запросов удаленных пользователей к своим периферийным устройствам. 3. Средства запроса доступа к удаленным ресурсам и услугам и их использования - клиентская часть ОС (редиректор). Эта часть выполняет распознавание и перенаправление в сеть запросов к удаленным ресурсам от приложений и пользователей, при этом запрос поступает от приложения в локальной форме, а передается в сеть в другой форме, соответствующей требованиям сервера. Клиентская часть также осуществляет прием ответов от серверов и преобразование их в локальный формат, так что для приложения выполнение локальных и удаленных запросов неразличимо. 4. Коммуникационные средства ОС, с помощью которых происходит обмен сообщениями в сети. Эта часть обеспечивает адресацию и буферизацию сообщений, выбор маршрута передачи сообщения по сети, надежность передачи и т.п., то есть является средством транспортировки сообщений.


12 Оболочка

Средства управления локальными ресурсами (Локальная ОС)

Серверная часть

Клиентская часть

Средства предоставления собственных ресурсов в общее пользование

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

В сеть

Коммуникационные средства

Рисунок 2.1 – Структура сетевой ОС В зависимости от функций, возлагаемых на конкретный компьютер, в его операционной системе может отсутствовать либо клиентская, либо серверная части. На рисунке 2.2 показано взаимодействие сетевых компонентов. Здесь компьютер 1 выполняет роль "чистого" клиента, а компьютер 2 - роль "чистого" сервера, соответственно на первой машине отсутствует серверная часть, а на второй - клиентская. На рисунке отдельно показан компонент клиентской части - редиректор. Именно редиректор перехватывает все запросы, поступающие от приложений, и анализирует их. Если выдан запрос к ресурсу данного компьютера, то он переадресовывается соответствующей подсистеме локальной ОС, если же это запрос к удаленному ресурсу, то он переправляется в сеть. При этом клиентская часть преобразует запрос из локальной формы в сетевой формат и передает его транспортной подсистеме, которая отвечает за доставку сообщений указанному серверу. Серверная часть операционной системы компьютера 2 принимает запрос, преобразует его и передает для выполнения своей локальной ОС. После того, как результат получен, сервер обращается к транспортной подсистеме и направляет ответ клиенту, выдавшему запрос. Клиентская часть преобразует результат в соответствующий формат и адресует его тому приложению, которое выдало запрос.


13 Компьютер 1

Компьютер 2 Приложение 2

Приложение 1

Редиректор 1

Локальная ОС 1

Серверная часть 2

Локальная ОС 2

Клиентская часть 1

Локальные ресурсы

Коммуникацио нные средства

Коммуникацио нные средства

Локальные ресурсы

Рисунок 2.2 – Взаимодействие компонентов операционной системы при взаимодействии компьютеров На практике сложилось несколько подходов к построению сетевых операционных систем (Рисунок 2.3).

Оболочка

LAN Manager (над OS/2) Personal Ware (над DOS 7) Локальная ОС

NetWare (клиенты)

Windows NT Workstation ОС со встроенными сетевыми функциями

Windows NT Server NetWare (сервер)

Рисунок 2.3 – Варианты построения сетевых ОС Первые сетевые ОС представляли собой совокупность существующей локальной ОС и надстроенной над ней сетевой оболочки. При этом в локальную ОС встраивался минимум сетевых функций, необходимых для работы сетевой оболочки, которая выполняла основные сетевые функции.


14 Примером такого подхода является использование на каждой машине сети операционной системы MS DOS (у которой начиная с ее третьей версии появились такие встроенные функции, как блокировка файлов и записей, необходимые для совместного доступа к файлам). Принцип построения сетевых ОС в виде сетевой оболочки над локальной ОС используется и в современных ОС, таких, например, как LANtastic или Personal Ware. Однако более эффективным представляется путь разработки операционных систем, изначально предназначенных для работы в сети. Сетевые функции у ОС такого типа глубоко встроены в основные модули системы, что обеспечивает их логическую стройность, простоту эксплуатации и модификации, а также высокую производительность. Примером такой ОС является система Windows NT фирмы Microsoft, которая за счет встроенности сетевых средств обеспечивает более высокие показатели производительности и защищенности информации по сравнению с сетевой ОС LAN Manager той же фирмы (совместная разработка с IBM), являющейся надстройкой над локальной операционной системой OS/2. 2.2 Особенности алгоритмов управления ресурсами От эффективности алгоритмов управления локальными ресурсами компьютера во многом зависит эффективность всей сетевой ОС в целом. Поэтому, характеризуя сетевую ОС, часто приводят важнейшие особенности реализации функций ОС по управлению процессорами, памятью, внешними устройствами автономного компьютера. Так, например, в зависимости от особенностей использованного алгоритма управления процессором, операционные системы делят на многозадачные и однозадачные, многопользовательские и однопользовательские, на системы, поддерживающие многонитевую обработку и не поддерживающие ее, на многопроцессорные и однопроцессорные системы. 2.2.1 Однозадачные ОС Однозадачные ОС - такие, в которых в один момент времени может выполнятся одна программа. В настоящее время большинство разрабатываемых операционных систем многозадачные, однако есть исключения. Однозадачные ОС в основном выполняют функцию предоставления пользователю виртуальной машины, делая более простым и удобным процесс взаимодействия пользователя с компьютером. Однозадачные ОС включают средства управления периферийными устройствами, средства управления файлами, средства общения с пользователем. К однозадачным относятся: MS-DOS, MSX.


15 2.2.2 Однопользовательские ОС Главным отличием однопользовательских систем от многопользовательских является отсутствие средств защиты информации каждого пользователя от несанкционированного доступа других пользователей. Следует заметить, что не всякая многозадачная система является многопользовательской, и не всякая однопользовательская ОС является однозадачной. К однопользовательским ОС относится MS-DOS. 2.2.3 Многопроцессорная обработка Важным свойством ОС является отсутствие или наличие в ней средств поддержки многопроцессорной обработки - мультипроцессирование. Мультипроцессирование приводит к усложнению всех алгоритмов управления ресурсами. В наши дни становится общепринятым введение в ОС функций поддержки многопроцессорной обработки данных. Такие функции имеются в операционных системах Solaris 2.x фирмы Sun, Open Server 3.x компании Santa Crus Operations, OS/2 фирмы IBM, Windows NT фирмы Microsoft и NetWare 4.1 фирмы Novell. Многопроцессорные операционные системы могут классифицироваться по способу организации вычислительного процесса в системе с многопроцессорной архитектурой: − асимметричные ОС; − симметричные ОС. Асимметричная операционная система целиком выполняется только на одном из процессоров системы, распределяя прикладные задачи по остальным процессорам. Симметричная операционная система полностью децентрализована и использует весь пул процессоров, разделяя их между системными и прикладными задачами. Выше были рассмотрены характеристики ОС, связанные с управлением только одним типом ресурсов - процессором. Важное влияние на облик операционной системы в целом, на возможности ее использования в той или иной области оказывают особенности и других подсистем управления локальными ресурсами - подсистем управления памятью, файлами, устройствами ввода-вывода. Специфика ОС проявляется и в том, каким образом она реализует сетевые функции: распознавание и перенаправление в сеть запросов к удаленным ресурсам, передача сообщений по сети, выполнение удаленных запросов. При реализации сетевых функций возникает комплекс задач, связанных с распределенным характером хранения и обработки данных в сети: ведение справочной информации о всех доступных в сети ресурсах и серверах, адресация взаимодействующих процессов, обеспечение


16 прозрачности доступа, тиражирование поддержка безопасности данных.

данных,

согласование

копий,

2.3 Особенности областей использования Операционные системы подразделяются на три типа в соответствии с использованными при их разработке критериями эффективности:  системы пакетной обработки (например, OC EC);  системы разделения времени (UNIX, VMS);  системы реального времени (QNX, RT/11). 2.3.1 Системы разделения времени Операционные системы разделения времени позволяют реализовать возможность повышения производительности труда пользователя за счет его доступа к своей задаче в процессе ее выполнения и повышения производительности ВС за счет мультипрограммирования. Режим разделения времени создает иллюзию одновременного доступа нескольких пользователей ко всем вычислительным ресурсам ВС. Каждый пользователь общается с системой так, как если бы ему одному принадлежали все вычислительные ресурсы: он может остановить выполнение своей задачи в нужном месте, просмотреть требуемые области RAM, с заданного места выполнить свою программу по командам и т.д. На самом же деле каждый пользователь получает для своей задачи достаточную зону RAM, процессор и прочие вычислительные ресурсы только в течение определенного и достаточно малого интервала времени, как уже говорилось выше - кванта. Пропускная способность ВС в режиме разделения времени ниже, чем при обработке задач в режиме мультипрограммирования, из-за накладных расходов ОС, вызванных частыми переключениями процессора и главным образом многочисленными переносами задач из RAM на жесткий диск и обратно, то есть свопингами. Во многих пользовательских системах режим разделения времени сочетается с пакетной обработкой задач в режиме мультипрограммирования. В этом случае RAM ЭВМ разделяется на зону для пакетной обработки и на зону (или несколько зон в зависимости от емкости RAM) для выполнения задач в режиме разделения времени. Такое сочетание позволяет загружать процессор даже в ситуациях, когда все пользователи режима разделения времени остановят выполнение своих задач. Такие системы используются при решении научно- технических задач. При этом главное назначение таких ОС - обеспечение более высокой эффективности использования всех вычислительных ресурсов ВС и достижение максимальных удобств в работе пользователя. Однако использование операционных систем общего


17 назначения в условиях работы конкретного пользователя часто означает явную избыточность многих системных средств. В таких случаях применяют ОС специального назначения. 2.3.2 Системы реального времени Системы реального времени призваны исправить основной недостаток систем пакетной обработки - изоляцию пользователя-программиста от процесса выполнения его задач. Каждому пользователю системы разделения времени предоставляется терминал, с которого он может вести диалог со своей программой. Так как в системах разделения времени каждой задаче выделяется только квант процессорного времени, ни одна задача не занимает процессор надолго, и время ответа оказывается приемлемым. Если квант выбран достаточно небольшим, то у всех пользователей, одновременно работающих на одной и той же машине, складывается впечатление, что каждый из них единолично использует машину. Ясно, что системы разделения времени обладают меньшей пропускной способностью, чем системы пакетной обработки, так как на выполнение принимается каждая запущенная пользователем задача, а не та, которая "выгодна" системе, и, кроме того, имеются накладные расходы вычислительной мощности на более частое переключение процессора с задачи на задачу. Критерием эффективности систем разделения времени является не максимальная пропускная способность, а удобство и эффективность работы пользователя. 2.4 Организация оперативной памяти Оперативная память – энергозависимая часть системы компьютерной памяти, в которой, исходя из названия, временно хранятся данные и команды, необходимые процессору для выполнения им операции. Обязательным условием является адресуемость (каждое машинное слово имеет индивидуальный адрес) памяти. Оперативная память – важный ресурс любой вычислительной системы, без которого невозможно выполнение программ. Это разделяемый ресурс и выбранный механизм распределения оперативной памяти очень влияет на эффективность использования ресурсов системы, производительность и другие параметры. Существует много различных типов оперативной памяти, но с точки зрения физического принципа действия различают динамическую память и статическую память. Ячейки динамической памяти можно представить в виде микроконденсаторов, способных накапливать заряд на своих обкладках. Это наиболее распространенный и экономически доступный тип памяти.


18 Недостатки этого типа связаны, во-первых, с тем, что как при заряде, так и при разряде конденсаторов неизбежны переходные процессы, то есть запись данных происходит сравнительно медленно. Второй важный недостаток связан с тем, что заряды ячеек имеют свойство рассеиваться в пространстве, причем весьма быстро. Если оперативную память постоянно не «подзаряжать», утрата данных происходит через несколько сотых долей секунды. Для борьбы с этим явлением в компьютере происходит постоянная регенерация (освежение, подзарядка) ячеек оперативной памяти. 2.5 Средства взаимодействия процессов: семафоры Семафоры традиционно использовались для синхронизации процессов, обращающихся к разделяемым данным. Каждый процесс должен исключать для всех других процессов возможность одновременно с ним обращаться к этим данным (взаимоисключение). Когда процесс обращается к разделяемым данным, говорят, что он находится в своем критическом участке. Для решения задачи синхронизации необходимо, в случае если один процесс находится в критическом участке, исключить возможность вхождения для других процессов в их критические участки. Хотя бы для тех, которые обращаются к тем же самым разделяемым данным. Когда процесс выходит из своего критического участка, то одному из остальных процессов, ожидающих входа в свои критические участки, должно быть разрешено продолжить работу. Процессы должны как можно быстрее проходить свои критические участки и не должны в этот период блокироваться. Если процесс, находящийся в своем критическом участке, завершается (возможно, аварийно), то необходимо, чтобы некоторый другой процесс мог отменить режим взаимоисключения, предоставляя другим процессам возможность продолжить выполнение и войти в свои критические участки. Семафор - это защищенная переменная, значение которой можно опрашивать и менять только при помощи специальных операций wait и signal и операции инициализации init. Двоичные семафоры могут принимать только значения 0 и 1. Семафоры со счетчиками могут принимать неотрицательные целые значения. Операция wait(s) над семафором s состоит в следующем: if s > 0 s:=s-1 else (ожидать на s).

А операция signal(s) заключается в том, что: if (имеются процессы, которые ожидают на s) (разрешить одному из них продолжить работу) else s:=s+1


19 Операции являются неделимыми. Критические участки процессов обрамляются операциями wait(s) и signal(s). Если одновременно несколько процессов попытаются выполнить операцию wait(s), то это будет разрешено только одному из них, а остальным придется ждать. Семафоры со счетчиками используются, если некоторые ресурс выделяется из множества идентичных ресурсов. При инициализации такого семафора в его счетчике указывается число элементов множества. Каждая операция wait(s) уменьшает значения счетчика семафора s на 1, показывая, что некоторому процессу выделен один ресурс из множества. Каждая операция signal(s) увеличивает значение счетчика на 1, показывая, что процесс возвратил ресурс во множество. Если операция wait(s) выполняется, когда в счетчике содержится нуль (больше нет ресурсов), то соответствующий процесс ожидает, пока во множество не будет возвращен освободившийся ресурс, то есть пока не будет выполнена операция signal. 2.6 Управление процессами: квантование времени Квантование – это выделение для выполнения каждой программы установленного временного интервала (кванта). По завершении этого интервала данная программа приостанавливается и начинает выполняться следующая. ОС (супервизор, диспетчер, координатор) циклически просматривает свою очередь, предоставляя всем программам по очереди фиксированные кванты времени. Это наиболее простой способ управления более или менее однотипными задачами в системе разделения времени, которые запускаются с пользовательских терминалов, где каждому терминалу поставлена в соответствие некоторая фиксированная область оперативной памяти, и, где каждая задача запрашивает выполнение примерно одинаковых пользовательских функций. Как уже отмечалось ранее, начав выполнятся, задача становится процессом. В любом случае, ОС должна чем-то руководствоваться для определения момента времени для первого запуска процесса. Этот момент определяется на основании приоритета. Приоритет – это число, характеризующее степень привилегированности процесса (потока) при использовании ресурсов компьютера, в частности процессорного времени. Чем выше приоритет, тем выше привилегии, тем меньше времени процесс (поток) будет проводить в очередях. Изначально приоритет может присваиваться операционной системой, а точнее, ее компонентой – планировщиком задач. В соответствии с приоритетом из процессов, готовых выполнению, образуется очередь. Процессы с более высоким приоритетом располагаются ближе к началу очереди. Для равноприоритетных процессов используется принцип FIFO (первый пришедший, первым обслуживается). В зависимости от


20 предыстории временных потребностей процесса его приоритет, может изменяться, может быть и неявно. 2.7. Организация файловой системы UNIX Термин файловая система обозначает одновременно и иерархию каталогов и файлов, и часть ядра, управляющую доступом к каталогам и файлам. Организация файловой системы означает рассмотрение структур, в которые могут быть организованы файлы на носителях данных. Существует несколько видов таких структур: линейные, древовидные, объектные и другие, но в настоящее время широко распространены только древовидные структуры. Каждый файл в древовидной структуре расположен в определенном хранилище файлов — каталоге, каждый каталог, в свою очередь, также расположен в некотором каталоге. Таким образом, по принципу вложения элементов файловой системы (файлов и каталогов) друг в друга строится дерево, вершинами которого являются непустые каталоги, а листьями — файлы или пустые каталоги. Корень такого дерева имеет название корневой каталог и обозначается каким-либо специальным символом или группой символов (например, «/» в UNIX или «C:» в операционной системе Windows). Каждому файлу соответствует некоторое имя, определяющее его расположение в дереве файловой системы. Полное имя файла состоит из имен всех вершин дерева файловой системы, через которые можно пройти от корня до данного файла (каталога), записывая их слева направо и разделяя специальными символами-разделителями. В настоящее время существует огромное количество файловых систем, каждая из которых используется для определенной цели: для быстрого доступа к данным, для обеспечения целостности данных при сбоях системы, для простоты реализации, для компактного хранения данных, и т. д. Однако среди всего множества файловых систем можно выделить такие, которые обладают рядом схожих признаков, а именно: Файлы и каталоги имеют несколько идентификаторов: помимо имён, с которыми обычно работают пользователи, каждому файлу соответствует уникальный в рамках файловой системы номер. Этот номер, называемый индексом файла, соответствует индексному узлу (i-node) — структуре на диске, в которой хранится служебная информация (так называемые «метаданные») о файле: расположение данных файла на диске, длина файла, владелец файла, права доступа и т. п. Таблица же связок типа «имя файла—inode» — есть не что иное как содержимое каталогов. Таким образом, каждый файл характеризуется одним i-node, но может быть связан с несколькими именами — в UNIX это называют жёсткими ссылками (Рисунок 2.4). При такой схеме физическое удаление данных файла


21 с носителя происходит только тогда, когда удаляется последняя из существующих жёстких ссылок на этот файл.

Рисунок 2.4 – Пример жесткой ссылки Важной особенностью таких файловых систем является то, что имена файлов зависят от регистра, другими словами файлы test.txt и TEST.txt отличаются (т. е. могут находиться в одном каталоге и быть при этом разными файлами). В определенных блоках физического носителя данных находится т. н. суперблок (Рисунок 2.5). Местоположение суперблока на носителе определяется при создании файловой системы. Суперблок — это наиболее ответственная область файловой системы, содержащая информацию, необходимую для работы файловой системы в целом, а также — для её идентификации. В суперблоке находится «магическое число» — идентификатор файловой системы, отличающий её от других файловых систем, список свободных блоков, список свободных индексных узлов (inode) и некоторая другая служебная информация. Помимо каталогов и обычных файлов для хранения информации, ФС может содержать следующие виды файлов: Специальный файл устройства – обеспечивает доступ к физическому устройству. При создании такого устройства указывается тип устройства (блочное или символьное), старший номер — индекс драйвера в таблице драйверов операционной системы имладший номер — параметр, передаваемый драйверу, поддерживающему несколько устройств, для уточнения о каком «подустройстве» идет речь (например, о каком из нескольких IDE-устройств или COM-портов). Именованный канал – используется для передачи данных между процессами, работает по принципу двунаправленной очереди (FIFO).


22 Является одним из способов обмена данными между изолированными процессами.

Рисунок 2.5 – Структура файловой системы Символьная ссылка – особый тип файла, содержимое которого — не данные, а имя какого-либо другого файла. Для пользователя такой файл в большинстве ситуаций неотличим от того, на который он ссылается: операции чтения, записи и пр. над символьной ссылкой работают так, как если бы они производились непосредственно над тем файлом, на который указывает ссылка. Символьные ссылки могут указывать также и на каталог: в этом случае они «работают» как каталоги (Рисунок 2.6).

Рисунок 2.6 – Пример символьной ссылки Символьная ссылка имеет ряд преимуществ по сравнению с жёсткой ссылкой: она может использоваться для связи файлов в разных файловых


23 системах (ведь номера индексных узлов уникальны только в рамках одной файловой системы). Кроме того, существование файла-ссылки совершенно независимо от существования того файла, на который он ссылается, поскольку в ссылке хранится только имя целевого файла, и нет никакой привязки к индексному узлу. Поэтому возможно удалять файл и ссылку независимо: причём в случае удаления целевого файла символьная ссылка продолжит существовать, но останется «битой», т. е. не позволяющей перейти ни к какому файлу. Сокет – предназначен для взаимодействия между процессами через специальное API, схожее с TCP/IP-сокетеми. Устроенные подобным образом файловые системы наследуют особенности оригинальной UNIX. К ним можно отнести, например: s5 (используемая в версиях UNIX System V), ufs (BSD UNIX), ext2, ext3, reiserfs (Linux), qnxfs (QNX). Все эти файловые системы различаются форматами внутренних структур, но совместимы с точки зрения основных концепций.


24 3 ВЫБОР АРХИТЕКТУРЫ ВЫЧИСЛИТЕЛЬНОЙ СИСТЕМЫ 3.1 Общая схема архитектуры вычислительной системы Как известно, сеть - это совокупность компьютеров, связанных друг с другом для обеспечения обмена данными и совместного использования различных ресурсов. Сетевыми ресурсами могут быть принтеры, файлы, прикладные программы и т.д. Для управления сетью разрабатываются специальные сетевые операционные системы, которые по своей организации можно разделить на одноранговые (Peer-To-Peer Network) и с выделенным файловым сервером (Dedicated File Server Network). В одноранговых сетях на каждой рабочей станции (компьютере) сети могут быть загружены две группы модулей: модули сервера и клиента . Загрузка в оперативную память (ОП) рабочей станции модулей сервера обеспечивает доступ других пользователей к ресурсам этого компьютера. А наличие модулей клиента позволяет пользователю иметь доступ к ресурсам других рабочих станций сети. Указанные группы программ могут использоваться в различных сочетаниях. Так рабочие станции (WorkStation) WS1 и WS2 могут выступать в качестве серверов, т.е. их ресурсами могут пользоваться другие станции. А станции WS1 и WS3 имеют доступ к другим компьютерам сети. К одноранговым относятся следующие сетевые операционные системы: − NetWare Lite, Personal NetWare (Novell), − Windows For Workgroups (Microsoft), − LANtastic (Artisoft). В сетях с выделенным сервером сетевая ОС инсталлируется и загружается на отдельной станции, которую называют файловым сервером (File Server). Рабочие станции имеют доступ к общим данным и другим ресурсам, хранящимся на файловом сервере. К операционным системам, которые устанавливаются на файловом сервере, относятся следующие ОС: − Vines 5.53 (Banyan), − OS/2 LAN Server 4.0 Advanced (IBM), − Windows NT Server 3.51 (Microsoft), − NetWare 3.x, 4.x (Novell). Рабочие станции могут функционировать под управлением различных ОС: − MS DOS, − OS/2, − UNIX, − Macintosh, − Windows NT Workstation.


25 3.2 Спецификация интерфейсов с ВУ Ещё в середине прошлого века, платы компьютера содержали до двух сотен микросхем. Материнская плата, формирующая основу вычислительной системы современного компьютера общего назначения, содержат две основные большие микросхемы: – так называемый северный мост (англ. North Bridge) – контроллерконцентратор памяти (MCH), который обеспечивает работу центрального процессора с оперативной памятью и видеоадаптера; – так называемый южный мост (англ. South Bridge) – контроллерконцентратор ввода-вывода (ICH), обеспечивающий работу контроллеров интегрированных в материнскую плату устройств (локальной вычислительной сети ЛВС, звуковой подсистемы, видеоадаптера в отдельном случае), а также взаимодействие с внешними устройствами, посредством организации шинного интерфейса. От микросхем чипсета зависят возможности работы установленных в вычислительной системе процессора, внутренних устройств (видеокарты, винчестера и др.). Любое внешнее устройство имеет контроллер, через который организуется аппаратное взаимодействие внешнего устройства с процессором. Каждому контроллеру внешнего устройства назначается свой адрес, по которому можно обращаться к нему. При обращении к устройству его адрес выставляется центральным процессором на шину адреса. По шине данных осуществляется обмен данными между устройствами и процессором. Общая схема архитектуры вычислительной системы, спецификации интерфейсов с ВУ показана на рисунке 3.1. 3.3 Архитектура процессора Архитектура процессора — количественная составляющая компонентов микроархитектуры вычислительной машины (процессора компьютера) (например, регистр флагов или регистры процессора), рассматриваемая IT-специалистами в аспекте прикладной деятельности. Сетевые процессоры сегодня находят широкое применение в самых разных сегментах рынка сетевого оборудования, а в ходе дальнейшего развития сетей потребуется создание инфраструктуры для предоставления различных интеллектуальных сервисов с высокими требованиями к пропускной способности сети. Эффективность работы процессоров в этих приложениях будет зависеть от степени интеллектуальности сервисов, предоставляемых процессором сетевому оборудованию и его производительности. В связи с возрастающей сложностью требований со стороны сетевой инфраструктуры


26 основным показателем производительности сетевого процессора становится пропускная способность при углубленном анализе пакетов на скоростях, сравнимых со скоростями передачи данных.

Рисунок 3.1 – Общая схема архитектуры вычислительной системы, спецификации интерфейсов с ВУ Скорости передачи информации и требования к обработке данных в разных сегментах сети существенно различаются, поэтому унифицированный подход к сетевой обработке уже не может обеспечивать сбалансированное сочетание производительности пакетной обработки и стоимости. Чтобы приблизить время создания следующего поколения сервисов, корпорация Intel расширила свой ассортимент сетевых процессоров, представив три новых семейства сетевых процессоров, построенных на базе архитектуры Intel Internet Exchange Architecture (Intel IXA) и предназначенных для разных сегментов рынка сетевого оборудования: для оборудования абонентов, для доступа к сетям, для работы на границах сетей и для магистральных сетей. Новые семейства сетевых процессоров дают возможность поставщикам сетевого оборудования


27 предлагать своим клиентам оптимальное сочетание настраиваемых и наращиваемых сервисов. Кроме того, каждое семейство сетевых процессоров предоставляет поставщикам всеобъемлющую среду разработки, включающую программное обеспечение, инструментарий и платформы для разработки, которые позволяют ускорить выпуск соответствующих устройств и снизить затраты. На рисунке 3.1 представлена разработанная схема микропроцессора. Адресная шина 8

Шина данных

8 8

8 DAR

PC ST

0

7

8

0

7

АЛУ

Сел ект ор

8 0

7

RI0

0

7

RI1

z ACH 0

c

p

k

ACL

7

8

15

8

IC

8

8

0

7

8 Дешифратор

8 УУС

z c p k

8

Рисунок 3.2 –Схема микропроцессора 3.3.1 Методы адресации процессора Intel Непосредственная адресация. Операнд(ы) располагаются в самой команде, в ее последних байтах. Эти байты, как правило, находятся во внутренней очереди команд процессора, поэтому доступ к ним осуществляется также достаточно быстро. Прямая адресация. В составе команды находится не сам операнд, а его адрес. Это простейший способ обратиться к данным, находящимся в ОЗУ. Базовая адресация. В этом случае адрес операнда (исполнительный адрес) получается, как сумма содержимого регистров BX или BP и числовой константы, называемой смещением (displacement). Если использован регистр ВХ, то будет происходить обращение к сегменту данных в ОЗУ, а если регистр ВР – то к сегменту стека. Такой вид адресации можно, например,


28 использовать для доступа к элементу некоего массива, номер которого заранее известен: регистр ВХ указывает на начало массива, а смещение представляет собой номер элемента. Стековая адресация является разновидностью неявной. Операнд находится в стеке, на вершину которого указывает регистр SP. Относительная адресация в микропроцессорах фирмы Intel не применяется к командам обработки данных, а используется лишь в командах переходов, вызовов подпрограмм и управления циклами. Адрес перехода образуется как смещение относительно текущего содержимого счетчика команд. 3.3.2 Система команд В соответствии с требованием функциональной полноты система команд включает следующие операции: − загрузку регистров и запись в память; − сложение и вычитание целых чисел; − поразрядные логические операции; − условные и безусловные переходы; − изменение содержимого разрядов регистра кода условия (флажков); − ввод и вывод; − останов, вызов подпрограмм и возврат из них. Система команд обеспечивает с помощью вышеприведенных команд организацию циклов, переход к подпрограмме и возврат. Модификация данных обеспечивается наличием команд загрузки, записи в память, арифметических и логических команд, изменяющих содержимое аккумуляторов и регистров общего назначения. Система команд микропроцессора представлена в таблице 3.1. Таблица 3.1 – Система команд микропроцессора № п/п 1 2

Название команды Мнемокод Сложение ADD H аккумулятора с регистром ADD HA ADD HN

3

ADD L

4

ADD LA

5

ADD LN

6 7

Вычитание аккумулятора регистра

из SUB H

КОП 0000 000a 0 7 0000 0010 0 7 0000 0011 0 7 0000 010a 0 7 0000 0110 0 7 0000 0111 0 7 0000 100a 0 7

ОП1, ОП2

Операция ACH + Ri

aaaa aaaa 8 15 dddd dddd 8 15 ACL + Ri aaaa aaaa 8 15 dddd dddd 8 15 ACH - Ri


29 Продолжение таблицы 3.1 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34

SUB HL SUB HN SUB L SUB LA SUB LN Логическое «И» AND H для аккум, и регистра AND HL AND HN AND L AND LA AND LN Исключающее XOR H ИЛИ для аккум, и регистра XOR HL XOR HN XOR L XOR LA XOR LN Логическое OR H «ИЛИ» для аккум, и регистра OR HL OR HN OR L OR LA OR LN Отрицание для NOT H аккумулятора NOT HL NOT HN NOT L

0000 1010 0 7 0000 1011 0 7 0000 110a 0 7 0000 1110 0 7 0000 1111 0 7 0001 000a 0 7 0001 0010 0 7 0001 0011 0 7 0001 010a 0 7 0001 0110 0 7 0001 0111 0 7 0001 100a 0 7 0001 1010 0 7 0001 1011 0 7 0001 110a 0 7 0001 1110 0 7 0001 1111 0 7 0010 000a 0 7 0010 0010 0 7 0010 0011 0 7 0010 010a 0 7 0010 0110 0 7 0010 0111 0 7 0010 100a 0 7 0010 1010 0 7 0010 1011 0 7 0010 110a 0 7

aaaa aaaa 8 15 dddd dddd 8 15 ACL - Ri aaaa aaaa 8 15 dddd dddd 8 15 ACH AND Ri aaaa aaaa 8 15 dddd dddd 8 15 ACL AND Ri aaaa aaaa 8 15 dddd dddd 8 15 ACH XOR Ri aaaa aaaa 8 15 dddd dddd 8 15 ACL XOR Ri aaaa aaaa 8 15 dddd dddd 8 15 ACH OR Ri aaaa aaaa 8 15 dddd dddd 8 15 ACL OR Ri aaaa aaaa 8 15 dddd dddd 8 15 ACH NOT Ri aaaa aaaa 8 15 dddd dddd 8 15 ACL NOT Ri


30 Продолжение таблицы 3.1 NOT LA

35

NOT LN

36 37 38 39 40 41 42 43 44 45 46

Установка флага знака Установка флага переноса Установка флага четности Установка флага нуля Условный переход (если Z) Условный переход (если C) Условный переход (если P) Условный переход (если K) Переход на метку

Z

Непосредственная загрузка

LDIH

P K JMPZ JMPC JMPP JMPK JMPO

LDIL

47 48

C

Арифметический сдвиг влево

RAHL RALL

49

50

Арифметический сдвиг вправо

RAHR RALR

51

52

Циклический сдвиг влево

RCHL RCLL

53

54

Циклический сдвиг вправо

RCHR RCLR

55

56 57

Загрузка в регистр LDH из аккумулятора LDL

0010 1110 0 7 0010 1111 0 7 0011 0000 0 7 0011 0001 0 7 0011 0010 0 7 0011 0011 0 7 0011 0100 0 7 0011 0101 0 7 0011 0110 0 7 0011 0111 0 7 0011 1000 0 7 0011 1001 0 7 0011 1010 0 7 0011 1011 0 7 0011 1100 0 7

aaaa aaaa 8 15 dddd dddd 8 15 0/1->Z 0/1->C 0/1->P 0/1->K aaaa aaaa 8 15 aaaa aaaa 8 15 aaaa aaaa 8 15 aaaa aaaa 8 15 aaaa aaaa 8 15 aaaa aaaa 8 15 aaaa aaaa 8 15

0011 1101 0 7 0011 1110 0 7

0011 1111 0 7 0100 0000 0 7

0100 0001 0 7 0100 1110 0 7

0100 001a 0 7 0100 010a 0 7

aaaa aaaa 8 15 aaaa aaaa 8 15

S -> PC S -> PC S -> PC S -> PC S -> PC

Все биты А сдвигаются на один разряд влево, старший разряд переходит в С, а С в младший разряд. Все биты А сдвигаются на один разряд вправо, старший разряд переходит в С, а С в младший разряд. Все биты А смещаются на один разряд А переходит в его нулевой разряд и регистр признака С Все биты А смещаются на один разряд А переходит в его нулевой разряд и регистр признака С ACH -> Ri ACL -> Ri


31 Продолжение таблицы 3.1 58

Загрузка аккумулятора

MOVL Data

59 60 61 62

MOVH Data

Загрузка аккумулятор регистра Завершить программу

в MRAH из MRAL STOP

0100 0110 0 7 0100 0111 0 7 0100 100a 0 7 0100 101a 0 7 0100 1101 0 7

aaaa aaaa 8 15 aaaa aaaa 8 15 aaaa aaaa 8 15 aaaa aaaa 8 15

DATA -> ACH DATA -> ACL Ri-> ACH Ri-> ACL 0->PC

3.3.3 Система прерываний Прерывание - это прекращение выполнения текущей команды или текущей последовательности команд для обработки некоторого события специальной программой - обработчиком прерывания, с последующим возвратом к выполнению прерванной программы. Событие может быть вызвано особой ситуацией, сложившейся при выполнении программы, или сигналом от внешнего устройства. Прерывание используется для быстрой реакции процессора на особые ситуации, возникающие при выполнении программы и взаимодействии с внешними устройствами. Прерывания делятся на аппаратные и программные. Аппаратные прерывания используются для организации взаимодействия с внешними устройствами. Запросы аппаратных прерываний поступают на специальные входы микропроцессора. Они бывают: − маскируемые, которые могут быть замаскированы программными средствами компьютера; − немаскируемые, запрос от которых таким образом замаскирован быть не может. Программные прерывания вызываются следующими ситуациями: − особый случай, возникший при выполнении команды и препятствующий нормальному продолжению программы (переполнение, нарушение защиты памяти, отсутствие нужной страницы в оперативной памяти и т.п.); − наличие в программе специальной команды прерывания INT n, используемой обычно программистом при обращениях к специальным функциям операционной системы для ввода-вывода информации. При поступлении запроса прерывания компьютер выполняет следующую последовательность действий: 1) определение наиболее приоритетного незамаскированного запроса на прерывание (если одновременно поступило несколько запросов); 2) определение типа выбранного запроса; 3) сохранение текущего состояния счетчика команд и регистра флагов;


32 4) определение адреса обработчика прерывания по типу прерывания и передача управления первой команде этого обработчика; 5) выполнение программы - обработчика прерывания; 6) восстановление сохраненных значений счетчика команд и регистра флагов прерванной программы; 7) продолжение выполнения прерванной программы. Этапы 1-4 выполняются аппаратными средствами ПК автоматически при появлении запроса прерывания. Этап 6 также выполняется аппаратно по команде возврата из обработчика прерывания. Список прерываний микропроцессора представлен в таблице 3.2. Таблица 3.2 – Список прерываний № Тип прерывания Наименование IRQ 1 Программное Деление на 0 IRQ 2 Программное Переполнение IRQ 3 Программное Память

IRQ 4

Программное

Память

IRQ 5 IRQ 6 IRQ 7

Аппаратное Аппаратное Аппаратное

IRQ 8 IRQ 9

Аппаратное Аппаратное

Клавиатура ЖД Контроллер USB Сетевая карта ожидание

Условие возникновения Деление на 0 Переполнение стека Неправильное обращение к памяти – выход за пределы сегмента Неправильное обращение к памяти – нарушение уровня доступа Нажатие клавиши Прерывания жесткого диска Прерывания контроллера USB Прерывания сетевой карты Приостановка выполнения задачи

3.4 Аппаратные средства обеспечения защиты Под аппаратными средствами защиты понимаются специальные средства, непосредственно входящие в состав технического обеспечения и выполняющие функции защиты как самостоятельно, так и в комплексе с другими средствами, например с программными. Можно выделить некоторые наиболее важные элементы аппаратной защиты: − защита от сбоев в электропитании; − защита от сбоев серверов, рабочих станций и локальных компьютеров; − защита от сбоев устройств для хранения информации; − защита от утечек информации электромагнитных излучений.


33 3.4.1 Защита от сбоев в электропитании Наиболее надежным средством предотвращения потерь информации при кратковременном отключении электроэнергии в настоящее время является установка источников бесперебойного питания (UPS). Различные по своим техническим и потребительским характеристикам, подобные устройства могут обеспечить питание всей локальной сети или отдельной компьютера в течение какого-то промежутка времени, достаточного для восстановления подачи напряжения или для сохранения информации на магнитные носители. В противном случае используется следующая функция подобных устройств – компьютер получает сигнал, что UPS перешел на работу от собственных аккумуляторов и время такой автономной работы ограничено. Тогда компьютер выполняет действия по корректному завершению всех выполняющихся программ и отключается (команда SHUTDOWN). Большинство источников бесперебойного питания одновременно выполняет функции и стабилизатора напряжения, является дополнительной защитой от скачков напряжения в сети. Многие современные сетевые устройства - серверы, концентраторы, мосты и т.д. - оснащены собственными дублированными системами электропитания. Крупные организации имеют собственные аварийные электрогенераторы или резервные линии электропитания. Эти линии подключены к разным подстанциям, и при выходе из строя одной них электроснабжение осуществляется с резервной подстанции. 3.4.2 Защита от сбоев процессоров Один из методов такой защиты - это резервирование особо важных компьютерных подсистем. Пример – симметричное мультипроцессирование. В системе используется более двух процессоров, и в случае сбоя одного из них, второй продолжает работу так, что пользователи вычислительной системы даже ничего не замечают. Естественно на такую защиту требуется гораздо больше средств.

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


34 устройства записи на магнитные ленты (стример), на компакт-диски многоразового использования, на оптические диски и т.д. В крупных корпоративных сетях наиболее предпочтительно организовать выделенный специализированный архивационный сервер. Специалисты рекомендуют хранить дубликаты архивов наиболее ценных данных в другом здании, на случай пожара или стихийного бедствия. В некоторых случаях, когда подобные сбои и потеря информации могут привести к неприемлемой остановке работы - применяются система зеркальных винчестеров. Резервная копия информации формируется в реальном времени, то есть в любой момент времени при выходе из строя одного винчестера система сразу же начинает работать с другим. Вместе с тем, кроме аппаратных средств резервного копирования данных существуют и чисто программные средства архивации.

3.4.4 Защита от утечек информации электромагнитных излучений Прохождение электрических сигналов по цепям ПК и соединительным кабелям сопровождается возникновением побочных электромагнитных излучений (ПЭМИ) в окружающей среде. Распространение побочных электромагнитных излучений за пределы контролируемой территории на десятки, сотни, а иногда и тысячи метров, создает предпосылки для утечки информации, так как возможен ее перехват с помощью специальных технических средств контроля. В персональном компьютере кроме проводных линий связи также основными источниками электромагнитных излучений являются мониторы, принтеры, накопители на магнитных дисках, а также центральный процессор. Исследования показывают, что излучение видеосигнала монитора является достаточно мощным, широкополосным и охватывает диапазон метровых и дециметровых волн. Для уменьшения уровня побочных электромагнитных излучений применяют специальные средства защиты информации: экранирование, фильтрацию, заземление, электромагнитное зашумление, а также средства ослабления уровней нежелательных электромагнитных излучений и наводок при помощи различных резистивных и поглощающих согласованных нагрузок. При контроле защиты информации ПК используются специально разработанные тестовые программы, а также специальная аппаратура контроля уровня излучения, которые определяют режим работы ПК, обеспечивающий совместно с другими техническими средствами скрытый режим работы для различных средств разведки. Используется аппаратное запрещение доступа к винчестеру с терминала. Этот достигается с помощью ключа пользователя, которым он замыкает свой винчестер. При этом происходит запрещение доступа к контроллеру дисков и не обрабатывается не один сигнал поступающих от других устройств, кроме определенного сигнала, который генерируется при


35 отмыкании винчестера ключом пользователя. Используется программноаппаратное запрещение доступа на запуск ПК на уровне BIOS (паролирование); использование привилегированных команд; разделение сегментов по типам (например, кодовый сегмент или сегмент данных); введение прав доступа к сегментам и страницам (например, право только чтения или только исполнения).


36 4 ВЫТЕСНЯЮЩАЯ МНОГОЗАДАЧНОСТЬ 4.1 Понятие многозадачности Многозадачность — способность операционной системы (или программного окружения) поддерживать одновременное совместное выполнение и взаимодействие нескольких задач (программ, потоков исполнения) друг с другом и внешней средой. Если система может выполнять задачи только последовательно, начиная следующую только после завершения текущей, то система называется однозадачной. Первые системы были именно такими. Переходным звеном к многозадачным ОС является ОС пакетной обработки: будучи однозадачной по сути, такая система работает не с одним приложением, а потоком пакетов, которые последовательно обрабатывает (запуская функции или программы их обработки). Различают два основных типа псевдопараллельной многозадачности: − невытесняющая, требующая явной передачи управления между задачами в определённых точках по их инициативе; − вытесняющая в которой переключение между задачам происходит неявно, посредством диспетчера задач в произвольные моменты времени. Невытясняющая многозадачность, как наиболее примитивная, была создана первой и имеет свои достоинства и недостатки. В противоположность ей существует вытесняющая многозадачность. В ней организация взаимодействия между полностью возложена на программное окружение (а конкретно, диспетчер задач), позволяя нескольким задачам одновременно работать в системе так, как если бы каждая была единственной. При этом возможно вытеснение задачи в любой момент времени и в любой точке кода (за исключением мест, где это явно запрещено) с переключением на другую. Плюсы и минусы следующие: − не требует от задач заботы о переключении между ними, любая задача, пока от неё не требуется взаимодействия с другими задачами или пользоваться общими ресурсами может выглядеть так же, как если бы она была в однозадачном окружении; − задача может оперативно получить управление в случае необходимости вне зависимости от состояния других задач, что обеспечивает работу в реальном времени; − широки возможности реализации защиты операционной системой задач от ошибок и атак; − требует специальных методов синхронизации задач друг с другом во избежание неопределённых ситуаций и конфликтов; − нуждается в поддержке со стороны аппаратного обеспечения (как минимум для сохранения и восстановления состояния микропроцессора при переключении);


37 − требует больше системных ресурсов (память под стек и сохранение состояния для каждого процессора и время на переключение контекстов). Достоинства вытесняющей многозадачности оказываются наиболее существенными для большинства практических задач и поэтому практически все достаточно развитые современные операционные системы реализуют именно этот тип многозадачности. Эффективность многозадачной системы во многом зависит от способа диспетчеризации задач на исполнение. Для понимания диспетчеризации важным является понятие состояния задачи. Основные состояния задач такие: − выполняется; − готова к исполнению; − заблокирована. Задача находится в состоянии исполнения тогда, когда под неё выделен ресурс процессора и передано управление. Очевидно, что в системе не может быть выполняющихся задач больше, чем физических процессоров. Поэтому существует второе состояние — готовность к исполнению. Задача в это состояние тогда, когда она может исполняться, то есть не существует причин, вызывающих блокировку, но вычислительные ресурсы отданы под другие задачи. В третье состояние задача попадает при невозможности её исполнения в данный момент времени. Это может быть − ожидание какого либо события (открытия семафора, прихода сообщения и т. п.); − незавершённая инициализация (когда ещё не созданы другой задачей или системой начальные условия для запуска); − «заморозка» (явная остановка исполнения, обычно в отладочных целях); − завершение (состояние «зомби», когда исполнение уже закончено, но ресурсы ещё не освобождены) или какие-то ещё специфические случаи. Многие операционные системы рассматривают эти случаи как различные, однако они имеют отражаются лишь в деталях реализации. В отличие от первых двух, состояние блокировки, вообще говоря не является обязательным. Достаточно стандартным является лишь случай ожидания, ходя и его можно реализовать пустым циклом. Однако это является пустой тратой процессорного времени, которое можно занять другой задачей, поэтому состояние блокировки существует практически во всех многозадачных ОС. Известно несколько основных стратегий диспетчеризации: − круговая (round-robin) – управление между задачами производится в каком-либо фиксированном порядке через определённые промежутки времени; − случайная (random) – каждый определённый промежуток времени управление передаётся на произвольную задачу;


38 − приоритетная (priority-driven) – каждая задача имеет уровень приоритета и управление получает незаблокированная задача имеющая наибольший уровень; − (deadline-driven) – передача управления производится в порядке, обеспечивающем выполнение задач в определённый срок. 4.2 Структура проекта в виде графа Структура проекта задается двудольным графом (аналогичным сети Петри), в котором каждый узел представляет собой блок обработки, а переход – точку синхронизации и/или передачи данных (рисунок 4.1). Вариант задания представлен в таблице 4.1. Таблица 4.1 – Вариант задания Номер варианта

Номер конфигурации

36

1

1 SS

2 SS

Типы блоков обработки (Nblock) 3 4 5 6 7 IT SS SC IT SS

Начало

1

3

2

5

6

7

4

8

Конец

Рисунок 4.1 – Структура проекта

8 IT


39 4.3 Реализация алгоритмов 4.3.1 Метод левых прямоугольников В общем виде формула левых прямоугольников на отрезке[x0;xn]выглядит следующим образом (см. формулу 4.1): (4.1) В данной формуле x0=a, xn=b, так как любой интеграл в общем виде выглядит (см. формулу 4.2): (4.2) h можно вычислить по формуле 4.3: ℎ=

𝑏−𝑎 𝑛

(4.3)

y0, y1,..., yn-1 - это значения соответствующей функции f(x) в точках x0, x1,..., xn-1 (xi=xi-1+h). 4.3.2 Метод правых прямоугольников В общем виде формула правых прямоугольников на отрезке [x0;xn] выглядит следующим образом (см. формулу 4.4): (4.4) В данной формуле x0=a, xn=b. h можно вычислить по формуле 4.3. y1, y2,..., yn - это значения соответствующей функции f(x) в точках x1, x2,..., xn (xi=xi-1+h). 4.3.3 Метод трапеций В общем случае формула трапеций выглядит следующим образом (см. формулу 4.5): (4.5)


40 ๐ 0 โ ะทะฝะฐั ะตะฝะธะต ั ั ะฝะบั ะธะธ ๐ (๐ ฅ) ะฒ ั ะพั ะบะต ๐ ฅ0 . ๐ ๐ โ ะทะฝะฐั ะตะฝะธะต ั ั ะฝะบั ะธะธ ๐ (๐ ฅ) ะฒ ั ะพั ะบะต ๐ . 4.4 ะ ั ะฑะพั ั ั ะตะดั ั ะฒ ะฒะทะฐะธะผะพะดะตะนั ั ะฒะธั ะฟะพั ะพะบะพะฒ ะกะตะผะฐั ะพั ะพั ะตะฝั ะฟะพั ะพะถ ะฝะฐ ะผั ั ั ะตะบั , ะฝะพ ะพั ะปะธั ะฐะตั ั ั ะพั ะฝะตะณะพ ั ะตะผ, ั ั ะพ ะผะพะถะตั ะธั ะฟะพะปั ะทะพะฒะฐั ั ั ั ะผะฝะพะถะตั ั ะฒะพะผ ะฟะพั ะพะบะพะฒ ะพะดะฝะพะฒั ะตะผะตะฝะฝะพ. ะกะตะผะฐั ะพั โ ั ั ะพ ะฟะพ ั ั ั ะธ ะผั ั ั ะตะบั ั ะฒะพะทะผะพะถะฝะพั ั ั ั ะฟะพะดั ั ะตั ะฐ: ะพะฝ ะฟะพะทะฒะพะปั ะตั ะพะฟั ะตะดะตะปั ั ั ั ั ะตั ั ะธะบ ะบะพะปะธั ะตั ั ะฒะฐ ะฟะพั ะพะบะพะฒ, ะบะพั ะพั ั ะผ ั ะฐะทั ะตั ะตะฝะพ ะพะดะฝะพะฒั ะตะผะตะฝะฝะพ ะฟะพะปั ั ะฐั ั ะดะพั ั ั ะฟ ะบ ะพั ั ะฐะฝั ะตะผะพะผั ั ะตะผะฐั ะพั ะพะผ ั ะตั ั ั ั ั . ะญั ะพะน ะฒะพะทะผะพะถะฝะพั ั ั ั ะผะพะถะฝะพ ะฟะพะปั ะทะพะฒะฐั ั ั ั , ะบะพะณะดะฐ ะธะผะตะตั ั ั ั ะตะปั ะน ั ั ะด ะดะพั ั ั ะฟะฝั ั ั ะตั ั ั ั ะพะฒ, ะธ ั ะฐะทั ะตั ะธั ั ะดะพั ั ั ะฟ ะบ ะบะฐะถะดะพะผั ะธะท ะฝะธั ะผะพะถะฝะพ ั ะพะปั ะบะพ ะพะฟั ะตะดะตะปะตะฝะฝะพะผั ะบะพะปะธั ะตั ั ะฒั ะฟะพั ะพะบะพะฒ. ะ ะฟั ะธะฒะพะดะธะผะพะผ ะฝะธะถะต ะฟั ะธะผะตั ะต ะฟั ะธะปะพะถะตะฝะธั ะฒ ะผะตั ะพะดะต Main ั ะพะทะดะฐั ั ั ั ั ะตั ั ั ะฟะพั ะพะบะพะฒ ะธ ะพะดะธะฝ ั ะตะผะฐั ะพั ั ะพ ั ั ะตั ั ะธะบะพะผ, ะดะปั ะบะพั ะพั ะพะณะพ ั ั ั ะฐะฝะฐะฒะปะธะฒะฐะตั ั ั ะทะฝะฐั ะตะฝะธะต 4. ะ ะบะพะฝั ั ั ั ะบั ะพั ะต ะบะปะฐั ั ะฐ Semaphore ะผะพะถะฝะพ ะพะฟั ะตะดะตะปะธั ั ั ั ะตั ั ะธะบ ะดะปั ะบะพะปะธั ะตั ั ะฒะฐ ะฑะปะพะบะธั ะพะฒะพะบ, ะบะพั ะพั ั ะต ะผะพะณั ั ะฟะพะปั ั ะฐั ั ั ั ั ั ะตะผะฐั ะพั ะพะผ (ะฒะพ ะฒั ะพั ะพะผ ะฟะฐั ะฐะผะตั ั ะต), ะธ ะบะพะปะธั ะตั ั ะฒะฐ ะฑะปะพะบะธั ะพะฒะพะบ, ะบะพั ะพั ั ะต ะดะพะปะถะฝั ะฑั ั ั ั ะฒะพะฑะพะดะฝั ะธะทะฝะฐั ะฐะปั ะฝะพ (ะฒ ะฟะตั ะฒะพะผ ะฟะฐั ะฐะผะตั ั ะต). ะ ั ะปะธ ะทะฝะฐั ะตะฝะธะต ะฟะตั ะฒะพะณะพ ะฟะฐั ะฐะผะตั ั ะฐ ะพะบะฐะทั ะฒะฐะตั ั ั ะฝะธะถะต ะทะฝะฐั ะตะฝะธั ะฒั ะพั ะพะณะพ ะฟะฐั ะฐะผะตั ั ะฐ, ั ะฐะทะฝะธั ะฐ ะผะตะถะดั ะฝะธะผะธ ะดะพะปะถะฝะฐ ั ะพะพั ะฒะตั ั ั ะฒั ั ั ะธะผ ะพะฑั ะฐะทะพะผ ะพั ั ะฐะถะฐั ั ั ั ะฝะฐ ะทะฝะฐั ะตะฝะธะธ ั ะปั ะต ะฒั ะดะตะปะตะฝะฝะพะณะพ ั ั ะตั ั ะธะบะฐ ั ะตะผะฐั ะพั ะฐ. ะ ะฐะบ ะธ ะผั ั ั ะตะบั ั , ั ะตะผะฐั ะพั ั ะผะพะถะตั ะฑั ั ั ะฝะฐะทะฝะฐั ะตะฝะพ ะบะฐะบะพะตะฝะธะฑั ะดั ะธะผั ะดะปั ั ะพะณะพ, ั ั ะพะฑั ะพะฝ ั ะฐะทะดะตะปั ะปั ั ะผะตะถะดั ั ะฐะทะปะธั ะฝั ะผะธ ะฟั ะพั ะตั ั ะฐะผะธ. ะ ะดะตั ั ะดะปั ั ะตะผะฐั ะพั ะฐ ะฝะธะบะฐะบะพะต ะธะผั ะฝะต ะพะฟั ะตะดะตะปั ั ั ั , ั ะฐะบ ั ั ะพ ะพะฝ ะธั ะฟะพะปั ะทั ะตั ั ั ะฒะฝั ั ั ะธ ั ะพะปั ะบะพ ะดะฐะฝะฝะพะณะพ ะฟั ะพั ะตั ั ะฐ. ะ ะพั ะปะต ั ะพะทะดะฐะฝะธั ะพะฑั ะตะบั ะฐ Semaphore ะฒั ะต ั ะตั ั ั ะฟะพั ะพะบะพะฒ ะทะฐะฟั ั ะบะฐั ั ั ั ะธ ะฟะพะปั ั ะฐั ั ะพะดะธะฝ ะธ ั ะพั ะถะต ั ะตะผะฐั ะพั . using System; using System.Threading; using System.Diagnostics; namespace Wrox.ProCSharp.Threading { class Program { static void Main() { int threadCount = 6; int semaphoreCount = 4; Semaphore semaphore = new Semaphore(semaphoreCount, semaphoreCount); Thread[] threads = new Thread[threadCount]; for (int i = 0; i < threadCount; i++) { threads[i] = new Thread(ThreadMain); threads[i].Start(semaphore); } for (int i = 0; i < threadCount; i++) { threads[i].Join(); } Console.WriteLine("ะ ั ะต ะฟะพั ะพะบะธ ะทะฐะฒะตั ั ะตะฝั "); } }

ะ ะพั ะฝะพะฒะฝะพะผ ะผะตั ะพะดะต ะฟะพั ะพะบะฐ โ ThreadMain () โ ะฟะพั ะพะบ ะฒั ะฟะพะปะฝั ะตั ะผะตั ะพะด WaitOne () ะดะปั ั ะพะณะพ, ั ั ะพะฑั ะทะฐะฑะปะพะบะธั ะพะฒะฐั ั ั ะตะผะฐั ะพั . ะ ะฐะฟะพะผะฝะธะผ, ั ั ะพ ั


41 семафора имеется счетчик со значением 4, означающим, что получить блокировку могут только 4 потока. Пятый поток должен лсдать своей очереди в течение 500 миллисекунд, которые указаны здесь в качестве максимального времени ожидания. Если по истечении этого периода времени ему так и не удается получить блокировку, он выводит на консоль сообщение и повторяет ожидание в цикле. Получив блокировку, поток выводит на консоль соответствующее сообщение, засыпает на некоторое время, а затем снимает блокировку. Опять-таки, при снятии блокировки важно, чтобы ресурс был освобожден в любом случае. Именно поэтому в последнем обработчике и вызывается метод Release () класса Semaphore. static void ThreadMain(object о) { Semaphore semaphore = о as Semaphore; Trace.Assert(semaphore != null, "о должны иметь тип Semaphore"); bool isCompleted - false; while (!isCompleted) { if (semaphore.WaitOne(600, false)) { try { Console.WriteLine ("Поток {0} заблокировал Thread.CurrentThread.ManagedThreadld); Thread.Sleep(2000); } finally { semaphore.Release(); Console.WriteLine("Поток {0} снял блокировку с семафора", Thread.CurrentThread.ManagedThreadld); isCompleted = true; } } else { Console.WriteLine("Тайм-аут для потока {0}; повторное Thread.CurrentThread.ManagedThreadld); } } }

семафор",

ожидание",

Запустив это приложение, действительно можно будет увидеть, что четыре потока выполняют блокировку незамедлительно. Потокам с идентификационными номерами 7 и 8 приходится ждать своей очереди. Процесс ожидания продолжается в цикле до тех пор, пока один из остальных потоков не освободит семафор. 4.5 Содержание log-файла после работы программы 00:00:00.0157925 00:00:00.0160883 00:00:00.0402123 00:00:00.0404831 00:00:00.0433665 00:00:00.0434867 00:00:00.0437312 00:00:00.0439598 00:00:00.0446677

Поток №1 начал работу Поток №2 начал работу Поток №4 начал работу Поток №3 начал работу Поток №1 закончил работу Поток №2 закончил работу Поток №3 закончил работу Поток №4 закончил работу Результат работы потока №1: 23,4258


42 00:00:00.0447844 00:00:00.0460879 00:00:00.0463301 00:00:00.0602115 00:00:00.0603773 00:00:00.0646550 00:00:00.0667580 00:00:00.0668243 00:00:00.0729517 00:00:00.0793846 00:00:00.0828038 00:00:00.3717592 00:00:00.3721050 00:00:00.8410880 00:00:00.8414632 00:00:00.8460950 00:00:00.8499057

Результат работы потока Результат работы потока Результат работы потока Поток №5 начал работу Поток №6 начал работу Поток №5 закончил работу Результат работы потока Поток №6 закончил работу Результат работы потока Поток №7 начал работу Поток №8 начал работу Поток №7 закончил работу Результат работы потока Поток №8 закончил работу Результат работы потока Выполнение окончено Результат 77201912,1396

№2: 45,8564 №3: 90,431 №4: 91,9898

№5: 2685 №6: 16437

№7: 3074995 №8: 4645105


43 5 ПРОЕКТИРОВАНИЕ КОМАНДНОГО ЯЗЫКА ОС При проектировании командного языка рекомендуется выделить основное множество команд, подлежащих дальнейшей реализации в проекте. Дополнительные сервисные команды представить только в таблице команд. Командный язык ОС включает:  интерактивные команды;  системные вызовы;  язык пакетных файлов. 5.1 Интерактивные команды Интерактивные команды вводятся пользователем с терминала:  основные: начало/завершение сеанса работы, создание/удаление элементов файловой структуры, копирование файлов;  дополнительные: установка и модификация параметров процессов/ресурсов, информационные команды.  При разработке интерактивных команд следует определить правила именования ресурсов системы: физических и логических устройств, каталогов, файлов, процессов и др. Правила именования:  физические устройства именуются кодом из латинских букв и цифр;  файлы, каталоги и процессы именуются произвольными именами, состоящих из любых букв и цифр в произвольном порядке (имена содержащие пробелы берутся в двойные кавычки). Список интерактивных команд приведен в таблице 5.1. Таблица 5.1 – Список интерактивных команд Параметр 1 Параметр 2 Значение Мнемоника Наименование Описание Диапазон Диапазон Значение по Тип по Тип значений значений умолчанию умолчанию Буквы Монтировать образ mnt Монтировать строка (рус./лат.) Unix.img файловой системы и цифры Размонтировать umnt Размонтировать текущий образ файловой системы Создать каталог с заданным именем и атрибутами (а – Буквы Создать архивный, r – только mkdir строка (рус./лат.) строка a, r, h, s, a--каталог чтение, h – скрытый, s и цифры – системный) (параметр 1 и 2 соответственно)


44 Продолжение таблицы 5.1 Удалить каталог

rmdir

Буквы строка (рус./лат.) и цифры

Буквы Редатировать строка (рус./лат.) (создать) файл и цифры

ed

Буквы (рус./лат.) строка и цифры, *, ? Буквы (рус./лат.) Копирование строка и цифры, *, ? Все буквы и цифры информация строка (первая буква) и * Буквы (рус./лат.) Перемещение строка и цифры, *, ? Удалить файл(ы)

rm

cp

inf

cd

-

-

-

-

-

строка a, r, h, s, -

-

-

-

a---

-

Буквы -

строка

-

строка

-

-

Удалить каталог с заданным именем редактировать файл с заданным именем, а если не существует, то создать его Удалить файл с заданным именем, (* - любые символы, ? – любой символ)

-

Копировать файлы и каталоги из источника в каталог назначения

dir, file, proc

Proc

Выводит информацию на экран о каталоге или файле

-

-

Перемещение в указанный каталог

(рус./лат.) и цифры

5.2. Системные вызовы Системные вызовы - это обращение к средствам ОС из выполняемых процессов. Эти средства ОС часто бывают скрыты от конечных пользователей. Для обеспечения переносимости программ работа в среде языков программирования в некоторой степени инвариантна по отношению к текущей операционной системе. Однако реализация алгоритмического языка для определенной операционной системы использует системные вызовы. Например, операторы ввода/ вывода в конечном счете транслируются в последовательности системных вызовов. Основные системные вызовы: ввод/вывод для физических устройств, файловый ввод/вывод. Как правило, ввод /вывод на физическом уровне является привилегированным средством и недоступен для прикладных процессов в целях обеспечения защиты информации на устройствах. Список системных вызовов приведен в таблице 5.2. Таблица 5.2 – Список системных вызовов Системная функция

open

Наименование

Открыть файл

Параметр 1 Параметр 2 Диапазон Диапазон Тип Тип значений значений Строк а

Буквы

число

0..216

Описание Открыть файл ([/r]-открыть для чтения; [/w]-открыть зля записи;[/p]-пароль для доступа;) 1 параметр – путь. имя, 2 параметр - адрес


45 Продолжение таблицы 5.2 close

Закрыть файл Число

0.. 216

-

-

setpos

Установить позицию Число 0.. 216 файла

число

0..232

write

Запись байта в Число 0.. 216 файл

число

0..255

число

0..255

-

-

-

-

число

0..max

-

-

read add kill

shmget

free

Чтение байта Число 0.. 216 из файла Создать строка Буквы процесс Уничтожить строка Буквы процесс Выделить память

число 0.. 216

Освободить число 0…216 память

Закрыть файл (параметр – адрес) Установить позицию в файле, заданным своим дескриптором (1 параметр – адрес файла, 2 параметр - позиция) Записать байт в файл и сместить позицию (1 параметр – адрес, 2 параметр – на сколько сместить позицию) Прочитать байт из файла и сместить позицию Создание дочернего процесса Принудительное уничтожение дочернего процесса Выделение памяти с 1 параметром – адрес и 2 параметром – кол-во (max – системная переменная, хранящая максимальное значение выделяемой памяти) Освобождение памяти по указателю (параметр – адрес)

5.3 Язык пакетных файлов Язык пакетных файлов должен обеспечивать условные и безусловные переходы, организацию циклов и вложенных параметрических конструкций. В простейшем случае командный файл представляет собой последовательность интерактивных команд, записанную в специальный файл, предназначенный для автоматического исполнения. В командные файлы также включают средства генерации имен и вызова вспомогательных командных файлов с указанием параметров. Команды пакетных файлов приведены в таблице 5.3. Таблица 5.3 – Команды пакетных файлов Параметр 1 Мнемоника

Наименование

Тип

Диапазон значений

goto <N>

переход на строку

число

1

pause <сообщение>

пауза выполнения и вывод сообщения

строка

-

Умолчания

«Нажмите любую клавишу…»

Параметр 2

-

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


46 Продолжение таблицы 5.3 if exp

переход если выражение exp истинно

строка

execute <N> <имя>

запуск процесса

число

while exp

цикл, если выражение exp истинно

строка

-

-

-

[0;31] 10 строка

-

-

-

если указанный процесс завершен то выполняется следующий блок команд запуск процесса с указанным приоритетом пока процесс активен, выполняется следующий блок команд


47 6 ОПРЕДЕЛЕНИЕ СОСТАВА И ОБЩЕЙ СТРУКТУРЫ СИСТЕМЫ 6.1 Состав ОС Любая сложная система должна иметь понятную и рациональную структуру, то есть разделяться на части — модули, имеющие вполне законченное функциональное назначение с четко оговоренными правилами взаимодействия. Ясное понимание роли каждого отдельного модуля существенно упрощает работу по модификации и развитию системы. Напротив, сложную систему без хорошей структуры чаще проще разработать заново, чем модернизировать. Функциональная сложность операционной системы неизбежно приводит к сложности ее архитектуры, под которой понимают структурную организацию ОС на основе различных программных модулей. Обычно в состав ОС входят исполняемые и объектные модули стандартных для данной ОС форматов, библиотеки разных типов, модули исходного текста программ, программные модули специального формата (например, загрузчик ОС, драйверы ввода-вывода), конфигурационные файлы, файлы документации, модули справочной системы и т. д. Большинство современных операционных систем представляют собой хорошо структурированные модульные системы, способные к развитию, расширению и переносу на новые платформы. Какой-либо единой архитектуры ОС не существует, но существуют универсальные подходы к структурированию ОС.

6.1.1 BIOS Содержит драйвера стандартных устройств, (в частности, накопителей дисководов, драйвер основной памяти), программу тестирования оборудования, программу начальной загрузки (SETUP) и интерпретатор одной из модификаций языка программирования высокого уровня BASIC, запускаемый в случае невозможности загрузить операционную систему. Программа, прошитая в BIOS, не зависит от операционной системы, однако, является ее неотъемлемой компонентой. Выход в утилиту конфигурирования BIOS осуществляется нажатием клавиши DEL, F2 и др. (зависит от производителя), сразу после окончания тестирования памяти при запуске компьютера.

6.1.2 Модуль взаимодействия с BIOS Файл BIOSInter.sys содержит расширение базовой системы ввода/вывода BIOS (Basic Input/Output System) и является интерфейсом


48 между операционной системой и BIOS. Расширение используется операционной системой для взаимодействия с аппаратурой компьютера и BIOS. Для того чтобы максимально уменьшить зависимость программ от особенностей аппаратного обеспечения компьютера используется многоступенчатая схема доступа программ к устройствам ввода/вывода. Согласно этой схеме программа никогда (в идеальном случае) не обращается непосредственно к портам аппаратуры. Вместо этого она взывает программное прерывание с нужным номером и запрашивает ту или иную функцию, загружая соответствующим образом регистры процессора. Все программные прерывания можно разделить на две группы. Первая группа - это прерывания базовой системы ввода/вывода BIOS. Обработчик этих прерываний записан в микросхеме постоянного запоминающего устройства (ПЗУ), расположенной на основной плате компьютера (motherboard). Обработчики прерываний BIOS работают с портами ввода/вывода стандартных устройств компьютера и обслуживают соответствующие аппаратные прерывания. В мире выпускается очень много различных моделей основных плат для компьютеров, совместимых в той или иной степени с IBM PC. Использование BIOS позволяет до некоторой степени стандартизовать программный интерфейс с аппаратурой, так как производитель основной платы может учесть в BIOS все аппаратные особенности. Вторая группа - прерывания разрабатываемой ОС. Обработчики этих прерываний находятся в файлах BIOSInter.sys и OS.sys. Расширение базовой системы ввода/вывода ОС, расположенное в файле BIOSInter.sys, является как бы прослойкой между операционной системой и BIOS. Для выполнения операций ввода/вывода ядро обращается как к самой базовой системе ввода/вывода BIOS, так и к ее расширению, загружаемому в оперативную память из файла BIOSInter.sys. 6.1.3 Модуль обработки прерываний Файл OS.sys является в некотором смысле набором программ обработки прерываний, в частности прерывания INT 21h. Это ядро операционной системы. Программы обращаются к прерыванию INT 21h в тех случаях, когда им нужно получить обслуживание от операционной системы. Например, заказать блок памяти, открыть файл или прочитать его содержимое, и т. д. 6.1.4 Командный процессор Файл command.com - это так называемый командный процессор.


49 Командный процессор предназначен для организации диалога с пользователем компьютера. Он анализирует введенные команды и организует их выполнение. Интерактивные команды обрабатываются именно командным процессором. Программист может написать свой собственный командный процессор и подключить его вместо стандартного. Новый командный процессор должен выполнять все функции, которые раньше выполняла стандартная программа command.com. 6.1.5 Блок начальной загрузки Блок начальной загрузки (Boot Record) — это очень короткая программа, единственная функция которой заключается в считывании с диска в оперативную память двух других частей системы — модуля расширения базовой системы ввода/вывода и модуля обработки прерываний. Boot Record размещается в 1-м секторе 0-дорожки 0-стороны системной дискеты и/или в 1-м секторе HDD-диска, в разделе, отведенном под ОС. Выполняет следующие функции: просматривает корневой каталог системного диска и проверяет, являются ли первые два файла в каталоге – файлами BIOSInter.sys и OS.SYS. Если ДА – загружает их в ОЗУ и передает управление ОС, если НЕТ – выдает сообщение на экране и ожидает нажатия какой-либо клавиши пользователем. 6.1.6 Драйвера устройств Драйверы представляют собой программы, обслуживающие различную аппаратуру. Кроме этого, в виде драйверов могут быть оформлены различные расширения системы, такие как система динамического сжатия данных на диске или система управления расширенной памятью. Обычно драйверы находятся в файлах, имеющих расширение имени *.sys, хотя есть и драйверы, встроенные в ОС. Драйвер подключается к операционной системе с помощью оператора device, расположенного в файле config.sys. 6.1.7 Файл CONFIG.SYS Файл config.sys представляет собой текстовый файл, предназначенный для определения конфигурации ОС, а также для загрузки драйверов и резидентных программ. Он создается автоматически программой установки ОС и затем при необходимости редактируется пользователем.


50 6.1.8 Порядок загрузки ОС 1. При включении PC вначале выполняются программы BIOS. 2. После тестирования и др.действий процедура POST(из модуля BIOS) осуществляет поиск и загрузку блока начальной загрузки (на устройствах, определенных программой SETUP). 3. Блок начальной загрузки производит поиск в корневом каталоге системной дискеты(диска) файлов BIOSInter.sys.sys и OS.sys (эти файлы должны быть первыми и именно в таком порядке). 4. Блок начальной загрузки производит загрузку файла BIOSInter.sys и передает ему управление. 5. BIOSInter.sys загружает и настраивает OS.sys, - определяет состояние подключенных устройств.  инициализирует подключенные устройства;  загружает необходимые драйверы устройств;  передает управление OS.sys. 6. OS.sys:  инициализирует (настраивает) свои внутренние рабочие таблицы;  загружает драйверы, указанные в файле config.sys;  загружает командный процессор (файл COMMAND.com). 7. Командный процессор выдает на экран Монитора системную подсказку ОС и ожидает команд Пользователя. 6.2 Структура ядра ОС Общая структура ядра ОС представлена на рисунке 6.1:

Блок начальной загрузки (BOOTREC)

Модуль взаимодействия с BIOS (BIOSInter.sys)

Модуль обработки прерываний (OS.sys)

Командный процессор (COMMAND.COM)

Рисунок 6.1 - Структура ядра проектируемой ОС


51 Операционная система предоставляет программе набор системных вызовов, реализованных с использованием механизма программных прерываний. Эти вызовы открывают прикладной программе доступ к системной информации, к системе консольного ввода/вывода, файловой системе, к системе управления программами и памятью, позволяют организовать обращение к драйверам периферийных устройств компьютера и т.д. Основные прерывания, использующиеся системой, указаны в таблице 6.1. Таблица 6.1 – Основные прерывания системы: Прерывание Описание INT 1h Это прерывание служит главным входом большинства функций ОС. INT 2h Завершение работы программы INT 3h Чтение диска с абсолютной адресацией секторов INT 4h Запись на диск с абсолютной адресацией секторов INT 5h Завершение работы программы с оставлением ее резидентной в памяти INT 6h Прерывание зарезервировано для ОС, используется резидентными программами INT 7h Выполнение команды ОС INT 8h Мультиплексное прерывание, используется для программы печати print и других резидентных программ; открывает доступ к внутренним функциям и структурам ОС

Все основные функции ОС вызываются с помощью прерывания INT 1h. Функции прерывания INT 1h можно разделить на следующие группы:  получение системной информации;  символьный ввод/вывод;  работа с файловой системой;  управление программами;  управление памятью;  связь с драйверами устройств;  прочий системный сервис. Номер функции задается при вызове прерывания INT 1h в регистре AH. 6.3 Способ реализации системных вызовов и передачи параметров В начале оперативной памяти персонального компьютера (в пределах первого килобайта) находится так называемая векторная таблица прерываний. Она состоит из 256 ячеек, хранящих адреса программобработчиков прерывания. Мы будем подробно изучать эту таблицу, а сейчас вспомним машинную команду INT <n>.


52 По команде INT <n> содержимое ячейки векторной таблицы прерываний с номером n помещается в адресные регистры процессора, причем в стеке запоминается текущее содержимое адресных регистров. Управление передается по адресу, записанному в ячейке таблицы. Программа-обработчик прерывания должна заканчиваться командой IRET, по которой из стека извлекается старое значение адресных регистров и управление передается обратно в программу, вызвавшую прерывание командой INT <n>. Процедура вызова и обработки программного прерывания похожа на процедуру вызова подпрограммы. Отличие заключается в том, что вызывающая программа "не знает" абсолютного адреса модуля обработки прерывания в памяти. Поэтому работа программ не зависит от адресов расположения модулей обработчиков прерывания, а также от адреса загрузки вызывающей программы. Для вызова модуля BIOS программа использует команду INT <n> с соответствующим номером n. Программа передает параметры модулям BIOS через регистры процессора, результат работы модуля возвращается также в регистрах. BIOS использует не все возможные номера прерываний. Часть из них предназначена для аппаратных прерываний от периферийных устройств, часть зарезервирована для ОС, часть - для программ пользователя.


53 7 ФОРМИРОВАНИЕ БАЗЫ ДАННЫХ ОС 7.1 Перечень, назначение и структура управляющих блоков Вслед за областью данных BIOS в оперативной памяти IBM PC располагается область данных ОС. Здесь располагаются внутренние переменные и структуры ОС. Основные структуры данных организованы в виде дерева. Корнем является векторная таблица связи, которая содержит адреса всех остальных структур:  список блоков управления памятью (MCB);  список блоков управления устройствами;  таблицу файлов, дисковые буфера. 7.1.1 Таблица связи управляющих блоков Векторная таблица связи содержит полезную информацию, открывающую доступ практически ко всем внутренним структурам данных операционной системы. Можно, например, получить доступ ко всем резидентным и загружаемым драйверам операционной системы. Можно узнать, какие дисковые устройства установлены в системе, и каковы их характеристики. Зная форматы управляющих блоков операционной системы, можно анализировать ошибочные ситуации, возникающие при отладке программного обеспечения, разрабатывать программы, отображающие внутреннее состояние системы и конфигурацию устройств. Ниже приведен список полей векторной таблицы связи. Для каждого поля указано его смещение относительно адреса, размер в байтах, имя и краткое описание (Таблица 7.1). Таблица 7.1 – Формат векторной таблицы связи Смещение, байт -2

Размер, байт 2

0

4

4

4

8

4

12

4

Имя поля mcb_seg dev_cb file_tab clock_dr

con_dr

max_btbl 16

2

Описание Сегмент первого блока памяти MCB Указатель на первый блок управления устройствами (Device Control Block) Указатель на таблицу файлов Указатель на драйвер CLOCK$ , установленный в файле config.sys или резидентный Указатель на драйвер CON , установленный в файле config.sys или резидентный Максимальный размер блока (в байтах) для устройства, выполняющего передачу данных отдельными блоками


54 Продолжение таблицы 7.1 18

4

22

4

26 30

4 2

32

1

33

1

Указатель на структуру, описывающую дисковые буферы Указатель на массив информации об устройствах Указатель на таблицу FCB Размер таблицы FCB Число устройств, выполняющих передачу данных отдельными блоками Значение LASTDRIVE в файле config.sys (по умолчанию равно 5)

disk_buf drv_info fcb_tabl fcb_size num_bdev lastdriv

7.1.2 Блоки управления памятью Вся оперативная память в ОС разделена на фрагменты, перед которыми распложены блоки управления памятью (MCB). Эти блоки описывают фрагменты памяти. Поле векторной таблицы связи mcb_seg содержит сегментный адрес первого блока управления памятью MCB . Блок MCB всегда начинается на границе параграфа, поэтому полный адрес первого блока будет равен mcb_seg:0. Внутри блока MCB хранится длина описываемого данным MCB фрагмента памяти. Следующий фрагмент памяти начинается сразу за предыдущим. Все блоки управления памятью связаны в список. Блоки MCB бывают двух типов - M и Z. M-блоки - это промежуточные блоки. Блок типа Z является последним блоком в списке и может быть только один. Формат блока управления памятью приведен в таблице 7.2. Таблица 7.2 – Формат блока управления памятью Смещение, байт 0 1

Размер, байт 1 2

Имя поля type owner

3 5

2 11

size reserve

Описание Тип блока MCB (M или Z) Сегментная компонента адреса владельца блока; этот блок всегда выровнен на границу параграфа (если 0, то блок описывает сам себя) Число параграфов в этом блоке Зарезервировано

7.1.3 Список управляющих блоков устройств Поле dev_cb векторной таблицы связи содержит дальний адрес списка блоков управления устройствами (Device Control Block). Device Control Block строится операционной системой для каждого дискового устройства и


55 содержит информацию о характеристиках этого устройства, указатель на заголовок драйвера, обслуживающего данное устройство и многое другое. Device Control Block может быть использован программами, которые выполняют доступ к диску на уровне секторов. Адрес блока управления памятью доступен через векторную таблицу связи. Формат блока управления устройствами приведен в таблице 7.3. Таблица 7.3 – Формат блока управления устройствами Смещение, байт 0

Размер, байт 1

1

1

2 4

2 1

5

1

6

2

9

2

11

2

13

2

16 17 19

1 2 4

23 24

1 1

25

4

29 31

2 2

Имя поля drv_num

Описание

Номер устройства (0 соответствует устройству А:, 1 - В: и т. д.) drv_numd Дополнительный номер устройства (используется, если драйвер обслуживает несколько устройств) sec_size Размер сектора в байтах clu_size Число, на единицу меньшее количества секторов в кластере clu_base Если содержимое этого поля не равно нулю, то для получения общего числа секторов в кластере надо возвести 2 в степень clu_base и получившееся число прибавить к clu_size boot_siz Количество зарезервированных секторов (загрузочные секторы, начало корневого каталога) max_dir Максимальное количество дескрипторов файлов в корневом каталоге (т. е. максимальное количество файлов, которое может содержать корневой каталог на этом устройстве) data_sec Номер первого сектора данных на диске (номер сектора, соответствующего кластеру с номером 2) hi_clust Максимальное количество кластеров (равно количеству кластеров данных, увеличенному на 1) reserv1 Зарезервировано root_sec Номер первого сектора корневого каталога drv_addr Дальний адрес заголовка драйвера, обслуживающего данное устройство media Байт описания среды носителя данных acc_flag Флаг доступа, 0 означает, что к устройству был доступ next Адрес следующего блока DCB .Для последнего блока в поле смещения находится число FFFFh reserv2 Зарезервировано built Значение 52EEh в этом поле означает, что блок DCB был сформирован.


56 7.2 Системная таблица файлов ОС создает системную таблицу файлов SFT (System File Table ) и помещает ее адрес в поле file_tab векторной таблицы связи. В этой таблице для каждого открытого файла хранится такая информация, как количество файловых идентификаторов, связанных с данным файлом, режим открытия файла (чтение, запись и т. д.), слово информации об устройстве, указатель на заголовок драйвера, обслуживающего данное устройство, элемент дескриптора файла (дата, время, имя файла, номер начального кластера, распределенного файлу), номер последнего прочитанного кластера и т. д. Эта информация может пригодиться, например, при организации защиты программы от копирования путем ее привязки к номерам занимаемых файлом программы кластеров. Формат таблицы системной таблицы файлов SFT в таблице 7.4. Таблица 7.4 – Формат системной таблицы файлов Смещение, Размер, Имя поля байт байт 0 4 next 4

2

file_count

Описание Указатель на следующую таблицу файлов SFT Количество файлов, описанных в этой таблице с помощью блоков DFCB

Блоки DFCB (по одному для каждого файла) расположены в конце таблицы SFT и имеют формат, описанный в таблице 7.5: Таблица 7.5 – Блоки DFCB Смещение, байт 0

Размер, Имя поля байт 2 handl_num

2

1

access_mode

3 5

2 2

reserv1 dev_info

7

4

driver

11

2

first_clu

13

2

time

15

2

date

17

4

fl_size

Описание Количество идентификаторов, связанных с данным файлом Режим доступа к файлу, заданный при открытии файла Зарезервировано Информация IOCTL , полученная для устройства, на котором расположен этот файл Указатель на драйвер, обслуживающий устройство, содержащее файл Номер первого кластера, распределенного файлу Время последнего изменения файла в упакованном формате Дата последнего изменения файла в упакованном формате Размер файла в байтах


57 Продолжение таблицы 7.5 21

4

offset

25 27 29 32 33 44 46

2 2 3 1 11 2 2

reserv2 reserv7 reserv3 reserv4 filename reserv5 ownr_psp

48 50

2 2

reserv6 last_clu

52

4

reserv8

Текущее смещение внутри файла в байтах Зарезервировано Зарезервировано Зарезервировано Зарезервировано Имя файла в формате Зарезервировано Адрес блока PSP программы, открывшей файл Зарезервировано Номер только что прочитанного кластера Зарезервировано

7.3 Список загружаемых драйверов устройств Все драйверы, резидентные или подключенные к операционной системе во время обработки файла config.sys , связаны в список. Первый драйвер - это так называемый NUL-драйвер. Он располагается в памяти всегда непосредственно после векторной таблицы связи. Драйвер имеет в самом начале специальный заголовок. Заголовок драйвера имеет формат, описанный в таблице 7.6. Таблица 7.6 – Формат заголовка драйвера Смещение, Размер, Имя поля байт байт 0 4 next

4 6 8

2 2 2

attrib strateg interrupt

10

8

dev_name

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

7.4 Блок описания дисков DINFO В структуре данных, адрес которой находится в поле drv_info векторной таблицы связи находится одномерный массив, описывающий


58 дисковые устройства. Количество элементов в массиве равно количеству дисковых устройств в системе. Для каждого диска в этом массиве можно найти текущий путь доступа в виде строки ASCIIZ , указатель на блок управления устройствами DDCB и номер начального кластера текущего каталога. Формат элемента массива DINFO описан в таблице 7.7. Таблица 7.7 – Формат элемента массива DINFO Смещение, байт 0 64 66 68 69

Размер, байт 64 2 2 1 4

Имя поля path reserv1 reserv2 reserv3 ddcb

73

2

cdir_clu

75 77 79 81

2 2 2 7

reserv4 reserv5 reserv6 reserv7

Описание Текущий путь доступа для диска Зарезервировано Зарезервировано Зарезервировано Адрес блока DDCB , соответствующего данному устройству Первый кластер текущего каталога на диске. 0 соответствует корневому каталогу, -1 - если к диску еще не обращались Зарезервировано Зарезервировано Зарезервировано Зарезервировано

7.5 Общая схема организации БД На рисунке 7.1 приведена схема взаимодействия управляющих блоков базы данных операционной системы. Таблица связи управляющих блоков Список блоков

Список блоков управления

Системная таблица

Список загружаемых драйверов

Блок описания дисков DINFO

Рисунок 7.1 – Схема Взаимодействия управляющих блоков


59 8 ПРОЕКТИРОВАНИЕ СТРУКТУРЫ И РЕАЛИЗАЦИЯ ЛОГИКИ УПРАВЛЕНИЯ ФАЙЛОВОЙ СИСТЕМЫ 8.1 Описание структур Образ файловой системы представлен классом UNIX. В нем содержатся ссылка на суперблок, и ссылки на текущие рабочие каталоги. Все классы, имеющие отношение к системе являются сериализуемыми, для упрощенного сохранения образа файловой системы, и тем самым обеспечения гибкости архитектуры. Таким образом, внесение изменений в код программы не требует переписывания функций сохранения и загрузки. [Serializable] //атрибут, сообщающий компилятору, что класс сериализуемый public class Unix { private static Unix instance; //объект, предсавляюий собой смонтированную файловую систему. Является частью реализации паттерна Singleton public CSuperBlock superBlock; //объект класса Суперблока public string CurrentCatalog = "/"; // адрес текущего рабочего каталога private Directory CurrentBlock; //текущая рабочая директроия private Directory NewBlock; //служит для проверки изменения текущего рабочего каталога const bool DIRECTORYC = false; const bool FILEC = true; }

Суперблок – описывает состояние файловой системы: какого она размера, сколько файлов может в ней храниться, где располагается свободное пространство, доступное для файловой системы, и другая информация. [Serializable] public class CSuperBlock { private string Header; //Заголовок ФС private string Version; //Версия программы в которой был создан образ private DateTime Data; // Дата создания образа public Directory FirstBlock; //Ссылка на первый блок private int INode; // нода public int CountOfMount; //Количество монтирований public string Name; //имя образа

public public public public

int BlockSize; //размер блока DataBlock[] blocks; //блоки данных int CountOfFreeBlocks; //Количество свободных блоков int MaxSizeOfImage; // размер образа

}

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


60 [Serializable] public class DataBlock { public string Data // данные { set; get; } public bool isBisy // используется ли данный блок { set; get; } }

– Родительский класс для хранения информации о иерархии данных. [Serializable] public class Block { public string Name; // имя файла или каталога public int INode; // номер нода public DateTime CreateDate; //дата создания файла public DateTime EditDate; // дата последнего изменения файла }

– Класс для хранения файла. public class File : Block { public List<int> datalinks; //индексы занимаемых блоков }

– Класс для хранения каталогов. [Serializable] public class Directory:Block { public List<Block> Childrens; // ссылки на дочерние файлы и каталоги }

8.2 Описание команд Для создания файла необходимо воспользоваться командой create <name> from <source>, где <name> - имя файла, from (необязательный параметр) - ключевое слово для открытия окна выбора файла источника а <source> - (необязательный параметр) - путь к файлуисточнику на диске. Для изменения рабочего каталога используется команда cd <path>, где <path> - путь к каталогу. Если путь начинается с «/», то путь указан относительно корня ФС, иначе путь относительно текущего каталога. Для открытия окна редактирования файла используется команда edit <path>, где <path> - относительный путь к файлу. Для удаления файла используется команда del <file>, где <file> - относительный путь к файлу. Для сохранения файла на жесткий диск необходимо воспользоваться командой save <file>, где <file> - относительный путь к


61 файлу/каталогу. В открывшемся окне выбрать папку для сохранения. Либо save <file> <path>, где <path> - путь к директории для сохранения. Для получения информации об образе служит команда info. Для получений информации о файле используется команда info <path>, где <path> - относительный путь к каталогу или файлу. Для редактирования каталога используется команда editdir <path>, где <path> - относительный путь к каталогу. Для редактирования текущего рабочего каталога служит команда edit this. Для того, чтобы создать каталог, нужно воспользоваться командой mkdir <dir>, где <dir> - имя каталога. Новый каталог создается в текущем рабочем каталоге. Для указания каталога-назначения используется команда mkdir <dir> <destination>, где <destination> - путь к каталогу, в котором создать новый каталог. Копирование файлов и каталогов производится командой copy <source> <path>, где <source> - исходный файл/каталог, <path> целевой каталог. Если путь целевого каталога начинается с «/», то путь указан относительно корня ФС, иначе путь относительно текущего каталогa. Чтобы удалить каталог используется команда rmdir <file>, где <dir> - относительный путь к каталогу. Команда qformat производит быстрое форматирование файловой системы. Команда clear производит очистку рабочего окна программы. 8.3 Программная реализация Эмулятор файловой системы написан на языке высокого уровня C# с использованием .NET Framework 4.0. Интерфейс программы создан на базе WinForms. Все элементы интерфейса приведены к общему стилю. В качестве окна вывода используется кастомизированный элемент управления ListBox, в котором реализована возможность переноса строки, а также изменен цвет выделения элемента. public class MultiLineListBox : ListBox { public MultiLineListBox() { this.DrawMode = DrawMode.OwnerDrawVariable; this.ScrollAlwaysVisible = false; } protected override void OnMeasureItem(MeasureItemEventArgs e) { if (Site != null) return; if (e.Index > -1)


62 { string s = Items[e.Index].ToString(); SizeF sf = e.Graphics.MeasureString(s, Font, Width); e.ItemHeight = (int)sf.Height; e.ItemWidth = Width; } } protected override void OnDrawItem(DrawItemEventArgs e) { if (Site != null) return; if (e.Index > -1) { string s = Items[e.Index].ToString(); /*Normal items*/ if ((e.State & DrawItemState.Focus) == 0) { e.Graphics.FillRectangle( new SolidBrush(Color.Black), e.Bounds); e.Graphics.DrawString(s, Font, new SolidBrush(Color.Lime), e.Bounds); } else /*Selected item, needs highlighting*/ { e.Graphics.FillRectangle( new SolidBrush(Color.Lime), e.Bounds); e.Graphics.DrawString(s, Font, new SolidBrush(Color.Black), e.Bounds); } } } }

По правому клику по ListBox открывается контекстное меню, которое позволяет скопировать выделенную команду в буфер обмена, или повторить её ввод. Для ввода команд используется TextBox, который содержит в себе путь к текущему рабочему каталогу. Структура файловой системы выводится при помощи TreeView. Директории имеют пометку (d), а файлы (f). Все вносимые в систему изменения сразу отображаются в TreeView. В правом нижнем углу главного окна находятся часы.


63 9 ОПРЕДЕЛЕНИЕ СОСТАВА И ОБЩЕЙ СТРУКТУРЫ ОС Основное назначение мультипрограммной ОС - обеспечить исполнение множества процессов, совместно использующих ресурсы компьютера. Поэтому ключом к пониманию функционирования ОС является диаграмма состояний процесса. Ядро ОС обеспечивает создание мультипроцессной среды и исполнение системных вызовов (примитивов) управления процессами, оперативной памятью и устройствами. Общая схема работы ядра раскрывает порядок выполнения основных системных вызовов и обработки прерываний. Так как язык системных вызовов реализуется, как правило, посредством механизма программных прерываний, ядро ОС является, по-существу, совокупностью обработчиков прерываний. 9.1 Структура системы Операционная система взаимодействует с аппаратурой непосредственно, обеспечивая обслуживание программ и их независимость от деталей аппаратной конфигурации. Если представить систему состоящей из пластов, в ней можно выделить системное ядро, изолированное от пользовательских программ. Поскольку прикладные программы не зависят от аппаратного устройства исполняющей их машины, то они могут быть перенесены из одной системы в другую (учитывая, что в этих программах не предусмотрена работа с некоторым точно определенным оборудованием). Программы, подобные командному процессору, взаимодействуют с ядром при помощи хорошо определенного набора обращений к операционной системе. Обращения к операционной системе понуждают ядро к выполнению различных операций, которых требует вызывающая программа, и обеспечивают обмен данными между ядром и программой. Другие прикладные программы располагаются выше указанных программ, на верхнем уровне. Самый общий взгляд на архитектуру UNIX позволяет увидеть двухуровневую модель системы, состоящую из пользовательской и системной части – ядра (рисунок 9.1). Ядро непосредственно взаимодействует с аппаратной частью компьютера, изолируя прикладные программы (процессы в пользовательской части операционной системы) от особенностей ее архитектуры. Ядро имеет набор услуг, предоставляемых прикладным программам посредством системных вызовов. Таким образом, в системе можно выделить два уровня привилегий: уровень системы (привилегии специального пользователя root).


64

Рисунок 9.1 Архитектура операционной системы Важную часть системных программ составляют демоны. Демон — это процесс, выполняющий определенную функцию в системе, который запускается при старте системы и не связан ни с одним пользовательским терминалом. Демоны предоставляют пользователям определенные сервисы, примерами которых могут служить системный журнал, веб-сервер и т. п. 9.2 Первоначальная загрузка Для того, чтобы перевести систему из неактивное состояние в активное, администратор выполняет процедуру "начальной загрузки". На разных машинах эта процедура имеет свои особенности, однако во всех случаях она реализует одну и ту же цель: загрузить копию операционной системы в основную память машины и запустить ее на исполнение. В системе UNIX процедура начальной загрузки заканчивается считыванием с диска в память блока начальной загрузки (нулевого блока). Программа, содержащаяся в этом блоке, загружает из файловой системы ядро ОС. После загрузки ядра системы в память, ядро запускается на выполнение. 9.3 Файловая система ОС Ниже рассматриваются ключевые особенности данной системы. Итак, файлы характеризуются:  иерархической структурой;  согласованной обработкой массивов данных;  возможностью создания и удаления файлов;  защитой информации в файлах и т.д. Файловая система представляет собой дерево, с единственной основой – корнем (root), обозначающимся как «/», а во главе этого корня стоит главный супер администратор с логином "root" по умолчанию. Каждая вершина в древовидной структуре файловой системы, кроме листьев, является каталогом файлов, а файлы, соответствующие дочерним вершинам, являются либо каталогами, либо обычными файлами, либо файлами устройств.


65 Каталоги похожи на обычные файлы в том смысле, что система представляет информацию в каталоге набором байтов, но эта информация включает в себя имена файлов в каталоге в объявленном формате. 9.4 Устройства Для пользователя система UNIX трактует устройства так, как если бы они были файлами. Устройства, для которых назначены специальные файлы устройств, становятся вершинами в структуре файловой системы. Обращение программ к устройствам имеет тот же самый синтаксис, что и обращение к обычным файлам; семантика операций чтения и записи по отношению к устройствам в большой степени совпадает с семантикой операций чтения и записи обычных файлов. Способ защиты устройств совпадает со способом защиты обычных файлов. 9.5 Процессы Программой называется исполняемый файл, а процессом называется последовательность операций программы или часть программы при ее выполнении. В системе UNIX может одновременно выполняться множество процессов (эту особенность иногда называют мультипрограммированием или многозадачным режимом), при чем их число логически не ограничивается, и множество частей программы (такой как copy) может одновременно находиться в системе. Различные системные операции позволяют процессам порождать новые процессы, завершают процессы, синхронизируют выполнение этапов процесса и управляют реакцией на наступление различных событий. Благодаря различным обращениям к операционной системе, процессы выполняются независимо друг от друга. Возможный набор состояний процесса содержится в следующем перечне: 1. Процесс выполняется в режиме задачи. 2. Процесс выполняется в режиме ядра. 3. Процесс не выполняется, но готов к запуску под управлением ядра. 4. Процесс приостановлен и находится в оперативной памяти. 5. Процесс готов к запуску, но программа подкачки (нулевой процесс) должна еще загрузить процесс в оперативную память, прежде чем он будет запущен под управлением ядра. 6. Процесс приостановлен и программа подкачки выгрузила его во внешнюю память, чтобы в оперативной памяти освободить место для других процессов. 7. Процесс возвращен из привилегированного режима (режима ядра) в непривилегированный (режим задачи), ядро резервирует его и переключает контекст на другой процесс.


66 8. Процесс вновь создан и находится в переходном состоянии; процесс существует, но не готов к выполнению, хотя и не приостановлен. Это состояние является начальным состоянием всех процессов, кроме нулевого. 9. Процесс вызывает системную функцию exit и прекращает существование. Однако, после него осталась запись, содержащая код выхода, и некоторая хронометрическая статистика, собираемая родительским процессом. Это состояние является последним состоянием процесса. 9.6 Диспетчеризация процессов в системе UNIX Рисунок 9.2 представляет собой полную диаграмму переходов процесса из состояния в состояние.

Рисунок 9.2 – Диаграмма переходов процесса из состояния в состояние


67 Ситуации, которые будут обсуждаться, несколько искусственны и процессы не всегда имеют дело с ними, но эти ситуации вполне применимы для иллюстрации различных переходов. Начальным состоянием модели является создание процесса родительским процессом с помощью системной функции fork; из этого состояния процесс неминуемо переходит в состояние готовности к запуску (3 или 5). Для простоты предположим, что процесс перешел в состояние «готовности к запуску в памяти» (3). Планировщик процессов в конечном счете выберет процесс для выполнения и процесс перейдет в состояние «выполнения в режиме ядра», где доиграет до конца роль, отведенную ему функцией fork. После всего этого процесс может перейти в состояние «выполнения в режиме задачи». По прохождении определенного периода времени может произойти прерывание работы процессора по таймеру и процесс снова перейдет в состояние «выполнения в режиме ядра». Как только программа обработки прерывания закончит работу, ядру может понадобиться подготовить к запуску другой процесс, поэтому первый процесс перейдет в состояние «резервирования», уступив дорогу второму процессу. Состояние «резервирования» в действительности не отличается от состояния «готовности к запуску в памяти» (пунктирная линия на рисунке, соединяющая между собой оба состояния, подчеркивает их эквивалентность), но они выделяются в отдельные состояния, чтобы подчеркнуть, что процесс, выполняющийся в режиме ядра, может быть зарезервирован только в том случае, если он собирается вернуться в режим задачи. Следовательно, ядро может при необходимости подкачивать процесс из состояния «резервирования». При известных условиях планировщик выберет процесс для исполнения и тот снова вернется в состояние «выполнения в режиме задачи». Когда процесс выполняет вызов системной функции, он из состояния «выполнения в режиме задачи» переходит в состояние «выполнения в режиме ядра». Предположим, что системной функции требуется ввод-вывод с диска и поэтому процесс вынужден дожидаться завершения ввода-вывода. Он переходит в состояние «приостанова в памяти», в котором будет находиться до тех пор, пока не получит извещения об окончании ввода-вывода. Когда ввод-вывод завершится, произойдет аппаратное прерывание работы центрального процессора и программа обработки прерывания возобновит выполнение процесса, в результате чего он перейдет в состояние «готовности к запуску в памяти». Если система выполняет множество процессов, которые одновременно никак не могут поместиться в оперативной памяти, и программа подкачки (нулевой процесс) выгружает один процесс, чтобы освободить место для другого процесса, находящегося в состоянии «готов к запуску, но выгружен». Первый процесс, выгруженный из оперативной памяти, переходит в то же состояние. Когда программа подкачки выбирает наиболее подходящий процесс для загрузки в оперативную память, этот процесс переходит в состояние «готовности к запуску в памяти». Планировщик выбирает процесс


68 для исполнения и он переходит в состояние «выполнения в режиме ядра». Когда процесс завершается, он исполняет системную функцию exit, последовательно переходя в состояния «выполнения в режиме ядра» и, наконец, в состояние «прекращения существования». Процесс может управлять некоторыми из переходов на уровне задачи. Во-первых, один процесс может создать другой процесс. Тем не менее, в какое из состояний процесс перейдет после создания (т. е. в состояние «готов к выполнению, находясь в памяти» или в состояние «готов к выполнению, но выгружен») зависит уже от ядра. Процессу эти состояния не подконтрольны. Во-вторых, процесс может обратиться к различным системным функциям чтобы перейти из состояния «выполнения в режиме задачи» в состояние «выполнения режиме ядра», а также перейти в режим ядра по своей собственной воле. Тем не менее момент возвращения из режима ядра от процесса уже не зависит; в результате каких-то событий он может никогда не вернуться из этого режима и из него перейдет в состояние «прекращения существования». Наконец, процесс может завершиться с помощью функции exit по своей собственной воле, но как указывалось ранее, внешние события могут потребовать завершения процесса без явного обращения к функции exit. Все остальные переходы относятся к жестко закрепленной части модели, закодированной в ядре, и являются результатом определенных событий, реагируя на них в соответствии с правилами, сформулированными в этой и последующих главах. Некоторые из правил уже упоминались: например, то, что процесс может выгрузить другой процесс, выполняющийся в ядре. Две принадлежащие ядру структуры данных описывают процесс: запись в таблице процессов и пространство процесса. Таблица процессов содержит поля, которые должны быть всегда доступны ядру, а пространство процесса — поля, необходимость в которых возникает только у выполняющегося процесса. Поэтому ядро выделяет место для пространства процесса только при создании процесса: в нем нет необходимости, если записи в таблице процессов не соответствует конкретный процесс. Запись в таблице процессов состоит из следующих полей: − Поле состояния, которое идентифицирует состояние процесса. − Поля, используемые ядром при размещении процесса и его пространства в основной или внешней памяти. Ядро использует информацию этих полей для переключения контекста на процесс, когда процесс переходит из состояния «готов к выполнению, находясь в памяти в состояние «выполнения в режиме ядра» или из состояния «резервирования» в состояние «выполнения в режиме задачи». Кроме того, ядро использует эту информацию при перекачки процессов из и в оперативную память (между двумя состояниями «в памяти» и двумя состояниями «выгружен»). Запись в таблице процессов содержит также поле, описывающее размер процесса и позволяющее ядру планировать выделение пространства для процесса.


69 1. Несколько пользовательских идентификаторов (UID), устанавливающих различные привилегии процесса. Поля UID, например, описывают совокупность процессов, могущих обмениваться сигналами. 2. Идентификаторы процесса (PID), указывающие взаимосвязь между процессами. Значения полей PID задаются при переходе процесса в состояние «создан» во время выполнения функции fork. 3. Дескриптор события (устанавливается тогда, когда процесс приостановлен). В данной главе будет рассмотрено использование дескриптора события в алгоритмах функций sleep и wakeup. 4. Параметры планирования, позволяющие ядру устанавливать порядок переход процессов из состояния «выполнения в режиме ядра» в состояние «выполнения в режиме задачи». 5. Поле сигналов, в котором перечисляются сигналы, посланные процессу, но еще н обработанные. 6. Различные таймеры, описывающие время выполнения процесса и использование ресурсов ядра и позволяющие осуществлять слежение за выполнением и вычислять приоритет планирования процесса. Одно из полей является таймером, который устанавливает пользователь и который необходим для посылки процессу сигнала тревоги. Пространство процесса содержит поля, дополнительно характеризующие состояния процесса. В системе разделения времени ядро предоставляет процессу ресурсы центрального процессора (ЦП) на интервал времени, называемый квантом, по истечении которого выгружает этот процесс и запускает другой, периодически переупорядочивая очередь процессов. Алгоритм планирования процессов в системе UNIX использует время выполнения в качестве параметра. Каждый активный процесс имеет приоритет планирования; ядро переключает контекст на процесс с наивысшим приоритетом. При переходе выполняющегося процесса из режима ядра в режим задачи ядро пересчитывает его приоритет, периодически и в режиме задачи переустанавливая приоритет каждого процесса, готового к выполнению. То есть, в соответствии с этим принципом ядро предоставляет процессу ресурсы ЦП на квант времени, по истечении которого выгружает этот процесс и возвращает его в одну из нескольких очередей, регулируемых приоритетами. Прежде чем процесс завершится, ему может потребоваться множество раз пройти через цикл с обратной связью. Когда ядро выполняет переключение контекста и восстанавливает контекст процесса, процесс возобновляет выполнение с точки приостановки. В основе многих вытесняющих алгоритмов планирования лежит концепция квантования. В соответствии с этой концепцией каждому потоку поочередно для выполнения предоставляется ограниченный непрерывный период процессорного времени — квант. Смена активного потока происходит, если:  поток завершился и покинул систему;  произошла ошибка;  поток перешел в состояние ожидания;


70  исчерпан квант процессорного времени, отведенный данному потоку. Поток, который исчерпал свой квант, переводится в состояние готовности и ожидает, когда ему будет предоставлен новый квант процессорного времени, а на выполнение в соответствии с определенным правилом выбирается новый поток из очереди готовых. Граф состояний потока, изображенный на рис. 9.3, соответствует алгоритму планирования, основанному на квантовании.

Готовность

Поток исчерпал квант

Ввод-вывод завершен

Ожидание

Потоку предоставлен квант Поток инициировал ввод-вывод

Выполнение Поток завершен или ошибка

Рисунок 9.3 – Граф состояний потока в системе с квантованием Чем больше потоков в системе, тем больше время ожидания, тем меньше возможности вести одновременную интерактивную работу нескольким пользователям. Но если величина кванта выбрана очень небольшой, то значение произведения q(n-l) все равно будет достаточно мало для того, чтобы пользователь не ощущал дискомфорта от присутствия в системе других пользователей. Типичное значение кванта в системах разделения времени составляет десятки миллисекунд. 9.7 Общий алгоритм диспетчеризации Сразу после переключения контекста ядро запускает алгоритм планирования выполнения процессов, выбирая на выполнение процесс с наивысшим приоритетом среди процессов, находящихся в состояниях "резервирования" и "готовности к выполнению, будучи загруженным в память". Рассматривать процессы, не загруженные в память, не имеет смысла, поскольку не будучи загружен, процесс не может выполняться. Если наивысший приоритет имеют сразу несколько процессов, ядро, используя принцип кольцевого списка (карусели), выбирает среди них тот процесс, который находится в состоянии "готовности к выполнению" дольше


71 остальных. Если ни один из процессов не может быть выбран для выполнения, ЦП простаивает до момента получения следующего прерывания, которое произойдет не позже чем через один таймерный тик; после обработки этого прерывания ядро снова запустит алгоритм планирования. 9.8 Архитектура ядра UNIX Ядро системы рассматривается как некоторая модель. Файловая подсистема и подсистема управления процессами, два главных компонента ядра. Файловая подсистема управляет файлами, размещает записи файлов, управляет свободным пространством, доступом к файлам и поиском данных для пользователей. Процессы взаимодействуют с подсистемой управления файлами, используя при этом совокупность специальных обращений к операционной системе, таких как open (для того, чтобы открыть файл на чтение или запись), close, read, write, stat (запросить атрибуты файла), chown (изменить запись с информацией о владельце файла) и chmod (изменить права доступа к файлу). Подсистема управления файлами обращается к данным, которые хранятся в файле, используя буферный механизм, управляющий потоком данных между ядром и устройствами внешней памяти. Буферный механизм, взаимодействуя с драйверами устройств ввода-вывода блоками, инициирует передачу данных к ядру и обратно. Большинство информационных структур ядра размещается в таблицах фиксированного размера, а не в динамически выделенной памяти. Простота алгоритмов ядра представляется более важной, чем сжатие последних байтов оперативной памяти. Обычно в алгоритмах для поиска свободных мест в таблицах используются несложные циклы и этот метод более понятен и иногда более эффективен по сравнению с более сложными схемами выделения памяти. Общая схема работы ядра ОС приведена на рисунке 9.4. Save (Current) Вход в ядро

KERNEL_ENTRY

Set (Kernel)

MN

M1 Перепланирование

Конец кванта Изменить состояние процесса Выход из ядра

Планировщик

KERNEL_EXIT

Выход без перепланирования

Set (Current)

Рисунок 9.4 — Общая схема работы ядра


72 9.9 Прерывания и особые ситуации Система UNIX позволяет таким устройствам, как внешние устройства ввода-вывода и системные часы, асинхронно прерывать работу центрального процессора. По получении сигнала прерывания ядро операционной системы сохраняет свой текущий контекст (застывший образ выполняемого процесса), устанавливает причину прерывания и обрабатывает прерывание. После того, как прерывание будет обработано ядром, прерванный контекст восстановится и работа продолжится так, как будто ничего не случилось. Устройствам обычно приписываются приоритеты в соответствии с очередностью обработки прерываний. В процессе обработки прерываний ядро учитывает их приоритеты и блокирует обслуживание прерывания с низким приоритетом на время обработки прерывания с более высоким приоритетом. Особые ситуации связаны с возникновением незапланированных событий, вызванных процессом, таких как недопустимая адресация, задание привилегированных команд, деление на ноль и т.д. Различают некоторое количество уровней прерывания. Их можно перечислить как (от высшего к низшему):  машинные сбои;  системные часы.  диск;  сетевое оборудование;  терминалы;  программное прерывание. Установка уровня прерывания на определенное значение отсекает прерывания этого и более низких уровней, разрешая обработку только прерываний с более высоким приоритетом. 9.10 Функции операционной системы Основными функциями ОС являются следующие функции. 1. Управление выполнением процессов посредством их создания, завершения или приостановки и организации взаимодействия между ними. 2. Планирование очередности предоставления выполняющимся процессам времени центрального процессора (диспетчеризация). Процессы работают с центральным процессором в режиме разделения времени: центральный процессор выполняет процесс, по завершении отсчитываемого ядром кванта времени процесс приостанавливается и ядро активизирует выполнение другого процесса. Позднее ядро запускает приостановленный процесс.


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


74 ВЫВОДЫ В ходе выполнения курсового проекта были изучены теоретические сведенья об аппаратных платформах для ОС, особенностях алгоритмов управления ресурсами, организации оперативной памяти, средствах взаимодействия процессов, а также о методах организации файловой системы. В результате выполнения данного курсового проекта была достигнута поставленная цель и спроектирована операционная система. Аппаратной платформой являются сети ЭВМ. Операционная система должна быть однозадачной, однопользовательской с многопроцессорной обработкой. К особенностям областей использования относятся системы разделения времени и системы реального времени. Организация оперативной памяти без использования внешней с переменными разделами. Средствами взаимодействия процессов являются семафоры. Управление процессами происходит посредствам квантования времени. Организация файловой системы UNIX. Разработанный программный продукт моделирует работу файловой системы UNIX, а также многопоточную обработку данных с использованием семафоров в качестве средств взаимодействия процессов. В дальнейшем для данного программного продукта может быть написано ядро и дополнительные модули для превращения его в простейшую полноценную операционную систему.


75 СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ 1. Таненбаум Э. Современные операционные системы. 3-е изд. –СПб.: Питер, 2010. – 1120 с.: ил. 2. Харт, Джонсон, М. Системное программное обеспечение в среде Windows, 3-е издание. :Пер.с англ. М. Издательский дом «Вильямс», 2005. – 592 с.:ил. 3. Олифер Н. А., Олифер В. Г. Компьютерные сети. Принципы, технологии, протоколы: Учебник для вузов, 4-е изд. - СПб.: Питер, 2011. – 944 с.: ил. 4. Олифер Н. А., Олифер В. Г. Сетевые операционные системы- СПб.: Питер, 2007. – 864 с.: ил. 5. Фленов М.Е. Библия C#. – 2-е изд., перераб. и доп. – СПб.: БХВПетербург. 2011. – 560с.: ил. + CD-ROM 6. Стиллмен Э., Грин Дж. Изучаем C#. 2-е изд. – СПб.: Питер, 2012. – 696 с.: ил. 7. Дрейер М. C#: Учебное пособие / М. Дрейер. Перевод с англ. под ред. В. Биллига—М.: Интернет-Университет Информационных Технологий; БИНОМ. Лаборатория знаний, 2009. — 128 с.: ил., табл. — (Лицей информационных технологий). 8. Магда Ю.С. UNIX для студента. – СПб.: БХВ-Петербург. 2010. 480 с.: ил.


76 ПРИЛОЖЕНИЕ А ТЕХНИЧЕСКОЕ ЗАДАНИЕ А.1 Общие сведения Название проекта: «Проектирование операционной системы с заданными характеристиками». Программный продукт проектируется студенткой 3-го курса Донецкого национального технического университета факультета компьютерных наук и технологий, группы ПОС-10б Лысаковой Натальей Владимировной. Основанием для разработки данного проекта является задание, выданное кафедрой Программного обеспечения интеллектуальных систем (ПОИС). Дата выдачи задания: 26.02.2013 Срок сдачи проекта: 22.05.2013 А.2 Назначение и цели создания проекта Целью создания проекта является приобретение практических навыков создания операционных систем и комплексного инженерного проектирования программного обеспечения. Проект предназначен для демонстрации работы алгоритмов, связанных с операционными системами. Проектируемая операционная система может быть использована в учебных заведениях в качестве наглядного пособия при обучении приемам и правилам построения интерактивной операционной системы. А.3 Требования к КП В курсовом проекте необходимо спроектировать компьютерную операционную систему c заданными характеристиками. А.3.1 Требования к задачам КП В КП должны быть реализованы следующие задачи:  реализация аппаратной платформы: большие ЭВМ;  реализация особенности алгоритмов управления ресурсами: однозадачные, однопользовательские, с многопроцессорной обработкой и вытесняющая многозадачность;  реализация особенности областей использования: системы разделения времени, системы реального времени;


77  организация оперативной памяти: без использования внешней памяти, с переменными разделами;  выполнение средств взаимодействия процессов: семафоры;  управление процессами: квантование времени;  выполнение организации файловой системы: UNIX. А.3.2 Требования к функциональности КП Разрабатываемый в рамках данного проекта программный продукт должен удовлетворять следующим требованиям к его функциональности: 1) реализация особенностей аппаратных платформ: сети ЭВМ; 2) реализация особенности алгоритмов управления ресурсами: однозадачные, однопользовательские, с многопроцессорной обработкой; 3) реализация особенности областей использования: системы разделения времени и системы реального времени; 4) организация оперативной памяти: без использования внешней памяти, с переменными разделами; 5) выполнение средств взаимодействия процессов: семафоры; 6) управление процессами: квантование времени; 7) выполнение организации файловой системы: UNIX. А.3.3 Требования к видам обеспечения А.3.3.1 Требования к программному обеспечению К программному обеспечению предъявляются следующие требования:  Windows 7/8;  .NET Framework 4.0 и выше;  Microsoft Visual Studio 2012;  текстовый редактор Microsoft Office 2007/2010/2013.

А.3.3.2 Требования к техническому обеспечению Требования к техническому обеспечению включают:  процессор с частотой 1,6 ГГц;  объем памяти RAM не менее 1 Гб;  свободное дисковое пространство около 10 Гб.  графический адаптер SVGA;  SVGA-монитор с разрешение 1024×768;


78  манипулятор типа «мышь»;  манипулятор типа «клавиатура». А.3.3.3 Требования к организационному обеспечению Организационным обеспечением по данному проекту составляет пояснительная записка. Она должна включать в себя следующие элементы:  Техническое задание на курсовой проект.  Руководство пользователя.  Экранные формы.  Листинг программы. А.4 Порядок защиты проекта При защите проекта должны соблюдаться следующие требования: 1. Защита проекта проводится в присутствии соответствующей приемной комиссии. 2. Для защиты проекта необходимо предоставить:  задание на курсовой проект;  пояснительную записку на курсовой проект;  исполнимый файл программы. А.5 Сроки выполнения курсового проекта Стадии и этапы разработки КП представлены в таблице 5.1. Таблица А.5.1 – Стадии и этапы разработки КП №

Этап

Срок выполнения

1

Выбор исходных элементов из классификатора для изучения проектного решения

1-2 недели

2

Разработка архитектуры аппаратных средств компьютера для реализации ОС

2-3 недели

3

Разработка интерфейса пользователя (командного языка)

3-4 недели

4

Проектирование основных структур данных и базы данных ОС

5-8 недели

5

Программирование и отладка средств взаимодействия процессов

9-10 недели

6

Программирование и отладка логики управления файловой системы

11 недели

7

Написание программной документации и оформление пояснительной записки

12 неделя

8

Защита КП

13 неделя


79 ПРИЛОЖЕНИЕ Б РУКОВОДСТВО ПОЛЬЗОВАТЕЛЯ Для запуска программного продукта в системе должен быть установлен .Net Framework 4 (или выше). Самую свежую версию можно скачать по ссылке http://www.microsoft.com/ru-ru/download/details.aspx?id=17851. Установить фреймфорк также можно из папки dist на прилагаемом диске. Для установки запустить файл dotNetFx40_Full_x86_x64.exe. Программный продукт не нуждается в установке, поэтому можно сразу приступать к работе. Для создания образа необходимо нажать кнопку «Создать». В появившемся окне ввести требуемые параметры, такие как имя образа, его размер и размер блока. Можно использовать параметры, введенные по умолчанию. Для загрузки уже существующего образа нужно нажать кнопку «Монтировать» и выбрать необходимый файл в появившемся окне. Для закрытия текущего открытого образа используется кнопка «Размонтировать». Все изменения, внесенные в образ, сохраняются автоматически, но существует кнопка «Сохранить», которая принудительно сохранят текущий образ на диск. Для создания файла необходимо воспользоваться командой create <name> from <source>, где <name> - имя файла, from (необязательный параметр) - ключевое слово для открытия окна выбора файла источника а <source> - (необязательный параметр) - путь к файлуисточнику на диске. Для открытия окна редактирования файла используется команда edit <path>, где <path> - относительный путь к файлу. Для удаления файла используется команда del <file>, где <file> - относительный путь к файлу. Команда qformat производит быстрое форматирование файловой системы. Команда clear производит очистку рабочего окна программы. Информацию об остальных командах можно прочитать во встроенной системе справки, которая вызывается командой hlp. Для изменения цветового оформления окна нажмите кнопку «Цвет окна» и выберите цвет самого окна и цвет текста. Для применения изменений нажмите кнопку «Изменить». Для получения информации о разработчике и программном продукте нажмите кнопку «О программе».


80 ПРИЛОЖЕНИЕ В ЛИСТИНГИ В.1 Реализация многопоточности using using using using using using using

System; System.Diagnostics; System.Drawing; System.Globalization; System.IO; System.Threading; System.Windows.Forms;

namespace oslab2 { public partial class Form1 : Form { private static readonly Semaphore Semaphores = new Semaphore(4, 4); private static Thread[] _threads = new Thread[8]; private static readonly double[] Rezult = new double[9]; private static readonly int[] States = new int[8]; private static bool _flag2; private static bool _flag5; private static bool _flag6; private static StreamWriter _strWriter; public static int Variant = 36; private readonly Bitmap _bitmap; private readonly Graphics _graphic; private readonly Stopwatch _stopwatch = new Stopwatch(); public Form1() { InitializeComponent(); CheckForIllegalCrossThreadCalls = false; _bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height); _graphic = Graphics.FromImage(_bitmap); } private void button1_Click(object sender, EventArgs e) { Clear(); if (PriorProcess() != null) { listBox1.Items.Add(_stopwatch.Elapsed.ToString() + "\t Запущен другой процесс"); return; } var thr = new Thread(AllThread); thr.Start(); _stopwatch.Start(); timer1.Enabled = true; //this.listBox1.Items.Add("Неуспели(("); } private void Clear() { _threads = new Thread[8]; _stopwatch.Reset(); label1.Text = _stopwatch.Elapsed.ToString(); listBox1.Items.Clear();


81 for (int i = 0; i < States.Length; i++) { States[i] = 0; } UpdateImage(); button3.Enabled = false; }

public Process PriorProcess() { Process mainProc = Process.GetCurrentProcess(); Process[] procs = Process.GetProcessesByName(mainProc.ProcessName); // ReSharper disable LoopCanBeConvertedToQuery // ReSharper disable ForCanBeConvertedToForeach for (int i = 0; i < procs.Length; i++) // ReSharper restore ForCanBeConvertedToForeach // ReSharper restore LoopCanBeConvertedToQuery { if ((procs[i].Id != mainProc.Id) && (procs[i].MainModule.FileName == mainProc.MainModule.FileName)) return procs[i]; } return null; } public void AllThread() { _threads[0] = new Thread(FirstThr); _threads[1] = new Thread(SecondThr); _threads[2] = new Thread(ThirdThr); _threads[3] = new Thread(FourthThr); _threads[4] = new Thread(FifthThr); _threads[5] = new Thread(SixthThr); _threads[6] = new Thread(SeventhThr); _threads[7] = new Thread(EighthThr); for (int i = 0; i < 4; i++) _threads[i].Start(); } private void FirstThr() { Semaphores.WaitOne(); listBox1.Items.Add(StartThread(1)); States[0] = 1; Rezult[0] = Ss(1, 1); try { Semaphores.Release(); listBox1.Items.Add(FinishThread(1)); listBox1.Items.Add(ResultThread(1) + Math.Round(Rezult[0], 4)); _threads[4].Start(); States[0] = 2; } catch (Exception) { listBox1.Items.Add(BreakThread(1)); } } private String StartThread(int i) { return _stopwatch.Elapsed.ToString() + "\tПоток №" + i + " начал работу";


82 } private String FinishThread(int i) { return _stopwatch.Elapsed.ToString() + "\tПоток №" + i + " закончил работу"; } private String ResultThread(int i) { return _stopwatch.Elapsed.ToString() + "\t }

Результат работы потока №" + i + ": ";

private String BreakThread(int i) { return _stopwatch.Elapsed.ToString() + "\tПоток №" + i + " прерван"; }

private void SecondThr() { Semaphores.WaitOne(); listBox1.Items.Add(StartThread(2)); States[1] = 1; Rezult[1] = Ss(1, 2); try { Semaphores.Release(); listBox1.Items.Add(FinishThread(2)); listBox1.Items.Add(ResultThread(2) + Math.Round(Rezult[1], 4)); _flag2 = true; States[1] = 2; if (_flag2 && _flag5 && _flag6) { _threads[6].Start(); _threads[7].Start(); } } catch (Exception) { listBox1.Items.Add(BreakThread(2)); } } private void ThirdThr() { Semaphores.WaitOne(); listBox1.Items.Add(StartThread(3)); States[2] = 1; Rezult[2] = It(1, 3); try { Semaphores.Release(); listBox1.Items.Add(FinishThread(3)); listBox1.Items.Add(ResultThread(3) + Math.Round(Rezult[2], 3)); States[2] = 2; _threads[5].Start(); } catch (Exception) { listBox1.Items.Add(BreakThread(3)); } } private void FourthThr()


83 { Semaphores.WaitOne(); listBox1.Items.Add(StartThread(4)); States[3] = 1; Rezult[3] = Ss(1, 4); try { Semaphores.Release(); listBox1.Items.Add(FinishThread(4)); listBox1.Items.Add(ResultThread(4) + Math.Round(Rezult[3], 4)); States[3] = 2; } catch (Exception) { listBox1.Items.Add(BreakThread(4)); } }

private void FifthThr() { Semaphores.WaitOne(); listBox1.Items.Add(StartThread(5)); States[4] = 1; Rezult[4] = Sc(Rezult[0], 5); try { Semaphores.Release(); listBox1.Items.Add(FinishThread(5)); listBox1.Items.Add(ResultThread(5) + Math.Round(Rezult[4])); _flag5 = true; States[4] = 2; if (_flag2 && _flag5 && _flag6) { _threads[6].Start(); _threads[7].Start(); } } catch (Exception) { listBox1.Items.Add(BreakThread(5)); } } private void SixthThr() { Semaphores.WaitOne(); listBox1.Items.Add(StartThread(6)); States[5] = 1; Rezult[5] = It(Rezult[2], 6); try { Semaphores.Release(); listBox1.Items.Add(FinishThread(6)); listBox1.Items.Add(ResultThread(6) + Math.Round(Rezult[5])); _flag6 = true; States[5] = 2; if (_flag2 && _flag5 && _flag6) { _threads[6].Start(); _threads[7].Start();


84 } } catch (Exception) { listBox1.Items.Add(BreakThread(6)); } } private void SeventhThr() { Semaphores.WaitOne(); listBox1.Items.Add(StartThread(7)); States[6] = 1; Rezult[6] = Ss(Rezult[1] + Rezult[4] + Rezult[5], 7); try { Semaphores.Release(); listBox1.Items.Add(FinishThread(7)); listBox1.Items.Add(ResultThread(7) + Math.Round(Rezult[6])); States[6] = 2; } catch (Exception) { listBox1.Items.Add(BreakThread(7)); } } private void EighthThr() { Semaphores.WaitOne(); listBox1.Items.Add(StartThread(8)); States[7] = 1; Rezult[7] = It(Rezult[1] + Rezult[4] + Rezult[5], 8); try { Semaphores.Release(); listBox1.Items.Add(FinishThread(8)); listBox1.Items.Add(ResultThread(8) + Math.Round(Rezult[7])); States[7] = 2; Finish(); } catch (Exception) { listBox1.Items.Add(BreakThread(8)); Finish(); } } private void Finish() { Rezult[8] = Rezult[3] + Rezult[6] + Rezult[7]; listBox1.Items.Add(_stopwatch.Elapsed.ToString() + "\tВыполнение окончено"); listBox1.Items.Add(_stopwatch.Elapsed.ToString() + "\t Результат " + Math.Round(Rezult[8], 4)); CreateLog(); timer1.Enabled = false; _stopwatch.Stop(); button3.Enabled = true; } public static double It(double rezult, int nomer)


85 { double arg = rezult*nomer*Variant; double n = arg; double wRezult = 0; double h = -2*arg/n; for (int i = 0; i < n - 1; i++) { wRezult += Math.Cos(-arg++)*Math.Sin(-arg++); } double rez = (Math.Cos(-arg)*Math.Sin(-arg) + Math.Cos(arg)*Math.Sin(arg))/2; rez += wRezult; rez *= h; return rez; } public static double Ss(double result, int nomer) { double arg = result*nomer*Variant; double rez = 0; for (int i = 0; i <= arg; i++) { rez += Math.Abs(Math.Sin(i)); } return rez; } public static double Sc(double result, int nomer) { double arg = result*nomer*Variant; double rez = 0; for (int i = 0; i <= arg; i++) { rez += Math.Abs(Math.Cos(i)); } return rez; } private void timer1_Tick(object sender, EventArgs e) { label1.Text = _stopwatch.Elapsed.ToString(); if (_stopwatch.Elapsed.Seconds == 20) { timer1.Enabled = false; _stopwatch.Stop(); listBox1.Items.Add(_stopwatch.Elapsed + "\t Вычисление не окончено."); Finish(); } } private void timer2_Tick(object sender, EventArgs e) { UpdateImage(); } private void UpdateImage() { Rectangle[] positions = { new Rectangle(25, 90, 45, 45), new Rectangle(90, 90, 45, 45), new Rectangle(165, 90, 45, 45), new Rectangle(228, 90, 45, 45), new Rectangle(25, 195, 45, 45), new Rectangle(165, 195, 45, 45), new Rectangle(80, 330, 45, 45),


86 new Rectangle(155, 330, 45, 45) }; var contur = new Pen(Color.Black); Brush brush = new SolidBrush(Color.Black); Brush red = new SolidBrush(Color.Red); Brush yellow = new SolidBrush(Color.Yellow); Brush green = new SolidBrush(Color.ForestGreen); var font = new Font("Arial", 10);

switch (States[0]) { case 0: brush = new SolidBrush(Color.White); _graphic.FillRectangle(red, 120, 20, 60, 30); break; case 1: brush = new SolidBrush(Color.Black); _graphic.FillRectangle(yellow, 120, 20, 60, 30); break; default: if (States[7] == 2) { brush = new SolidBrush(Color.White); _graphic.FillRectangle(green, 120, 20, 60, 30); } break; } _graphic.DrawString("Начало", font, brush, 125, 25); _graphic.DrawLine(contur, 25, 70, 275, 70); _graphic.DrawLine(contur, 28, 170, 70, 170); _graphic.DrawLine(contur, 160, 170, 220, 170); _graphic.DrawLine(contur, 30, 270, 225, 270); _graphic.DrawLine(contur, 25, 405, 275, 405); DrawArrow(_graphic, contur, 150, 50, 150, 70); DrawArrow(_graphic, contur, 48, 70, 48, 90); DrawArrow(_graphic, contur, 113, 70, 113, 90); DrawArrow(_graphic, contur, 187, 70, 187, 90); DrawArrow(_graphic, contur, 250, 70, 250, 90); DrawArrow(_graphic, contur, 48, 135, 48, 170); DrawArrow(_graphic, contur, 187, 135, 187, 170); DrawArrow(_graphic, contur, 113, 90, 113, 270); DrawArrow(_graphic, contur, 250, 90, 250, 405); DrawArrow(_graphic, contur, 48, 170, 48, 195); DrawArrow(_graphic, contur, 187, 170, 187, 195); DrawArrow(_graphic, contur, 48, 235, 48, 270); DrawArrow(_graphic, contur, 187, 235, 187, 270); DrawArrow(_graphic, contur, 103, 270, 103, 330); DrawArrow(_graphic, contur, 177, 270, 177, 330); DrawArrow(_graphic, contur, 103, 330, 103, 405); DrawArrow(_graphic, contur, 177, 330, 177, 405); DrawArrow(_graphic, contur, 150, 405, 150, 425); switch (States[0]) { case 0: brush = new SolidBrush(Color.White); _graphic.FillRectangle(red, 120, 425, 60, 30); break; case 1: brush = new SolidBrush(Color.Black); _graphic.FillRectangle(yellow, 120, 425, 60, 30); break; default:


87 if (States[7] == 2) { brush = new SolidBrush(Color.White); _graphic.FillRectangle(green, 120, 425, 60, 30); } break; } _graphic.DrawString("Конец", font, brush, 125, 430); for (int i = 0; i < States.Length; i++) { if (States[i] == 0) { brush = new SolidBrush(Color.White); _graphic.FillEllipse(red, positions[i]); } else if (States[i] == 1) { brush = new SolidBrush(Color.Black); _graphic.FillEllipse(yellow, positions[i]); } else if (States[i] == 2) { brush = new SolidBrush(Color.White); _graphic.FillEllipse(green, positions[i]); } _graphic.DrawEllipse(contur, positions[i]); _graphic.DrawString((i + 1).ToString(CultureInfo.InvariantCulture), font, brush, positions[i].X + 18, positions[i].Y + 15); } pictureBox1.Image = _bitmap; } public void CreateLog() { _strWriter = new StreamWriter("log.txt"); foreach (object item in listBox1.Items) { _strWriter.WriteLine(item); } _strWriter.Dispose(); } public void DrawArrow(Graphics g, Pen p, int sx, int sy, int fx, int fy) { g.DrawLine(p, sx, sy, fx, fy); g.DrawLine(p, fx, fy, fx - 5, fy - 5); g.DrawLine(p, fx, fy, fx + 5, fy - 5); } private void button2_Click(object sender, EventArgs e) { Process.Start("log.txt"); } private void button3_Click(object sender, EventArgs e) { Clear(); } } }


88 В.2 Реализация эмулятора файловой системы ////======== UNIX.cs ========/// using using using using using

System; System.Collections.Generic; System.IO; System.Linq; System.Windows.Forms;

namespace UNIX_FileSystem_Emulator.Classes { [Serializable] public class Unix { private const bool DIRECTORYC = false; private const bool FILEC = true; private static Unix _instance; public string CurrentCatalog = "/"; public CSuperBlock SuperBlock; private Directory _currentBlock; private Directory _newBlock; protected Unix(string name, int sizeOfImage, int sizeOfBlock) { SuperBlock = new CSuperBlock(name, sizeOfImage, sizeOfBlock); _currentBlock = SuperBlock.FirstBlock; _newBlock = _currentBlock; } public static Unix Instance { get { return _instance ?? (_instance = new Unix()); } } public void CreateInstance(string name, int sizeOfImage, int sizeOfBlock) { _instance = new Unix(name, sizeOfImage, sizeOfBlock); } public void CreateInstance(Unix fs) { _instance = fs; } public string[] MakeCommand(string command) { var temp = new[] {"Команда не распознана", " Используйте >hlp для получения справки о командах"}; string[] parse = command.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);

if (parse.Length > 1) { switch (parse[1].ToLower()) { case "create": if (parse.Length != 3 && parse.Length != 4) { temp = Help.CreateHelp(); } else {


89 if (parse.Length == 3) { if (parse[2] == "this") { temp = new[] { "Ошибка создания файла " + parse[2], "Невозможно создать файл с зарезервированным именем" }; break; } if (CreateFile(parse[2])) { temp = new[] {"Файл " + parse[2] + " создан"}; } else { temp = new[] { "Ошибка создания файла " + parse[2], "Возможно, файл с таким именем существует" }; } } else //4 { if (parse[3] == "from") { var openFileDialog1 = new OpenFileDialog { DefaultExt = "image", Filter = @"Текстовые файлы (*.txt)|*.txt" }; if (openFileDialog1.ShowDialog() == DialogResult.OK) { if (parse[2] == "this") { temp = new[] { "Ошибка создания файла " + parse[2], "Невозможно создать файл с зарезервированным именем" }; break; } if (CreateFromFile(parse[2], openFileDialog1.FileName)) { temp = new[] {"Файл " + parse[2] + " создан из " + openFileDialog1.FileName}; } else { var f = new FileInfo(openFileDialog1.FileName); temp = new[] { "Ошибка создания файла " + parse[2], "Возможно, файл с таким именем существует, или недостаточно места на диске." , "Свободно места :" + SuperBlock.GetFreeSize() + " байт", "Размер файла :" + f.Length + " байт" }; } }


90 } else { if (parse[2] == "this") { temp = new[] { "Ошибка создания файла " + parse[2], "Невозможно создать файл с зарезервированным именем" }; break; } if (CreateFromFile(parse[2], parse[3])) { temp = new[] {"Файл " + parse[2] + " создан из " + parse[3]}; } else { if (System.IO.File.Exists(parse[3])) { var f = new FileInfo(parse[3]); temp = new[] { "Ошибка создания файла " + parse[2], "Возможно, файл с таким именем существует или недостаточно места на диске" , "Свободно места :" + SuperBlock.GetFreeSize() + " байт", "Размер файла :" + f.Length + " байт" }; } else { temp = new[] { "Ошибка создания файла " + parse[2], "Файл не существует" }; } } } } } break; case "hlp": temp = Help.ShowHelp(); break; case "cd": if (parse.Length == 3) { if (SetWorkCatalog(parse[2])) { _currentBlock = _newBlock; if (parse[2][0] == '/') { CurrentCatalog = parse[2]; } else { CurrentCatalog += parse[2]; } temp = new[] {"Рабочий каталог изменен на " + parse[2]}; } else


91 { temp = new[] {"Рабочий каталог не изменен." + "Текущий рабочий каталог " + parse[2]}; } } else { temp = Help.CdHelp(); } break; case "edit": if (parse.Length == 3) { var f = (File) GetBlockByName(parse[2], FILEC); if (f != null) { var editor = new EditFileForm(f); if (editor.ShowDialog() == DialogResult.OK) { temp = editor.GetChangedFile() != null ? new[] {"Изменения в файле " + parse[2] + " успешно сохранены"} : new[] {"Не хватает места на диске. Файл " + parse[2] + " не сохранен"}; } else { temp = new[] {"Файл " + parse[2] + " не изменен"}; } } else { temp = new[] {"Файл " + parse[2] + " не найден"}; } } else { temp = Help.EditHelp(); } break; case "del": if (parse.Length == 3) { temp = DeleteBlock(parse[2], FILEC) ? new[] {"Файл " + parse[2] + " удален"} : new[] {"Файл " + parse[2] + " не удален"}; } else { temp = Help.DelHelp(); } break; case "copy": if (parse.Length == 4) { temp = CreateCopy(parse[2], parse[3]) ? new[] {"Файл " + parse[2] + " скопирован в " + parse[3]} : new[] {"Исходный файл " + parse[2] + " не существует"}; } else { temp = Help.CopyHelp(); } break; case "mkdir": if (parse.Length == 3)


92 { if (parse[2] == "this") { temp = new[] { "Ошибка создания каталога " + parse[2], "Невозможно создать файл с зарезервированным именем" }; break; } temp = CreateDir(parse[2]) ? new[] {"Каталог " + parse[2] + " создан"} : new[] {"Ошибка создания Каталога " + parse[2]}; } if (parse.Length == 4) { temp = CreateDir(parse[2], parse[3]) ? new[] {"Каталог " + parse[2] + " создан в " + parse[3]} : new[] {"Каталог " + parse[2] + " не создан"}; } else { Help.MkDirHelp(); } break; case "rmdir": if (parse.Length == 3) { temp = DeleteBlock(parse[2], DIRECTORYC) ? new[] {"Каталог " + parse[2] + " удален"} : new[] {"Каталог " + parse[2] + " не удален"}; } else { temp = Help.rmdirHelp(); } break; case "editdir": if (parse.Length == 3) { var f = (Directory) GetBlockByName(parse[2], DIRECTORYC); if (f != null) { var editor = new EditDirectoryForm(f); temp = editor.ShowDialog() == DialogResult.OK ? new[] {"Изменения в каталоге " + parse[2] + " успешно сохранены"} : new[] {"Каталог " + parse[2] + " не изменен"}; } else { temp = new[] {"Каталог " + parse[2] + " не найден"}; } } else { temp = Help.EditDirHelp(); } break; case "save": if (parse.Length == 3) { Block t = GetBlockByName(parse[2]); if (t != null) {


93 var f = new FolderBrowserDialog(); if (f.ShowDialog() == DialogResult.OK) { string path = f.SelectedPath; if (t is Directory) { SaveDirectoryToDisk(path, (Directory) t); temp = new[] {"Указанный каталог сохранен"}; } else { SaveFileToDisk(path, (File) t); temp = new[] {"Указанный файл сохренен"}; } } } else { temp = new[] {"Указанный файл не найден"}; } } else if (parse.Length == 4) { Block t = GetBlockByName(parse[2]); if (t != null) { if (System.IO.Directory.Exists(parse[3])) { string path = parse[3]; if (t is Directory) { SaveDirectoryToDisk(path, (Directory) t); temp = new[] {"Указанный каталог сохранен"}; } else { SaveFileToDisk(path, (File) t); temp = new[] {"Указанный файл сохренен"}; } } else { temp = new[] {"Указанный файл (каталог) не существует"}; } } } else { Help.SaveHelp(); } break; case "info": if (parse.Length != 2 && parse.Length != 3) { Help.InfoHelp(); } else { if (parse.Length == 2) temp = SuperBlock.SayHello('f'); else { Block bl = GetBlockByName(parse[2]);


94 if (bl != null) { var i = new InfoBlock(bl); i.ShowDialog(); temp = new string[] {}; } else { temp = new[] {"Файл/Каталог не найден"}; } } } break; case "qformat": SuperBlock.FirstBlock = new Directory("/", 2); CurrentCatalog = "/"; _currentBlock = _newBlock = SuperBlock.FirstBlock; foreach (DataBlock t in SuperBlock.Blocks) { t.IsBisy = false; } temp = new[] {"Быстрое форматирование прошло успешно"}; break; case "clear": temp = new[] {"del"}; break; } } return temp; } private void SaveFileToDisk(string path, File t) { var s = new StreamWriter(new FileStream(path + "\\" + t.Name, FileMode.Create)); foreach (int i in t.Datalinks) { s.WriteLine(SuperBlock.Blocks[i].Data); } s.Dispose(); } private void SaveDirectoryToDisk(string path, Directory directory) { System.IO.Directory.CreateDirectory(path + "\\" + directory.Name); path += "\\" + directory.Name; foreach (Block item in directory.Childrens) { if (item is File) { SaveFileToDisk(path, (File) item); } else { SaveDirectoryToDisk(path, (Directory) item); } } } private bool CreateDir(string name, string destination) { if (_currentBlock.Childrens.Any(item => item.Name == name)) { return false; }


95 Directory oldBlock = _currentBlock; if (SetWorkCatalog(destination)) { _currentBlock = _newBlock; _currentBlock.Childrens.Add(new Directory(name, SuperBlock.GetFreeINode())); _currentBlock = oldBlock; return true; } _currentBlock = oldBlock; return false; } private bool CreateDir(string name) { if (_currentBlock.Childrens.Any(item => item.Name == name)) { return false; } _currentBlock.Childrens.Add(new Directory(name, SuperBlock.GetFreeINode())); return true; } private bool CreateCopy(string source, string destination) { Directory oldBlock = _currentBlock; Block file; Block oldObj = GetBlockByName(source); if (oldObj == null) return false; if (oldObj is File) { var t = (File) oldObj; var tmp = new List<int>(); for (int i = 0; i < t.Datalinks.Count; i++) { tmp.Add(SuperBlock.GetFreeBlockNumber()); } file = new File(oldObj.Name, SuperBlock.GetFreeINode(), tmp); } else { var t = (Directory) oldObj; file = new Directory(t.Name, SuperBlock.GetFreeINode(), t.Childrens); } if (SetWorkCatalog(destination)) { if (_currentBlock == _newBlock) file.Name += "copy"; _currentBlock = _newBlock; _currentBlock.Childrens.Add(file); } _currentBlock = oldBlock; return true; } private Block GetBlockByName(string name) { if (name == "this")


96 return _currentBlock; return _currentBlock.Childrens.FirstOrDefault(item => item.Name == name); } private bool DeleteBlock(string name, bool mode) { if (mode) { for (int i = 0; i < _currentBlock.Childrens.Count; i++) { if (_currentBlock.Childrens[i].Name == name && _currentBlock.Childrens[i] is File) { var tmp = (File) _currentBlock.Childrens[i]; foreach (int item in tmp.Datalinks) { SuperBlock.Blocks[item] = new DataBlock(SuperBlock.BlockSize); } _currentBlock.Childrens.RemoveAt(i); return true; } } } else { for (int i = 0; i < _currentBlock.Childrens.Count; i++) { if (_currentBlock.Childrens[i].Name == name && _currentBlock.Childrens[i] is Directory) { _currentBlock.Childrens.RemoveAt(i); return true; } } } return false; } private Block GetBlockByName(string name, bool mode) { if (mode == FILEC) { return _currentBlock.Childrens.Where(item => item.Name == name && item is File) .Cast<File>() .FirstOrDefault(); } return _currentBlock.Childrens.Where(item => item.Name == name && item is Directory) .Cast<Directory>() .FirstOrDefault(); } private bool CreateFromFile(string name, string destination) { try { if (_currentBlock.Childrens.Any(item => item.Name == name)) { return false; } var fs = new StreamReader(new FileStream(destination, FileMode.Open)); var s = new List<int>();


97 while (!fs.EndOfStream) { int c = SuperBlock.GetFreeBlockNumber(); SuperBlock.Blocks[c].IsBisy = true; if (c == -1) { return false; } s.Add(c); var arr = new char[SuperBlock.BlockSize]; fs.Read(arr, 0, arr.Length); Array.Reverse(arr); int notNormCount = arr.TakeWhile(t => t == '\0').Count(); var narr = new char[arr.Length - notNormCount]; Array.Reverse(arr); for (int i = 0; i < narr.Length; i++) { narr[i] = arr[i]; } SuperBlock.Blocks[c].Data = new string(narr); } var tmp = new File(name, SuperBlock.GetFreeINode(), s); if (tmp.GetSize() <= SuperBlock.GetFreeSize()) { _currentBlock.Childrens.Add(tmp); } else { return false; } fs.Dispose(); return true; } catch (Exception ex) { MessageBox.Show(ex.Message); return false; } } private bool CreateFile(string name) { if (_currentBlock.Childrens.Any(item => item.Name == name)) { return false; } _currentBlock.Childrens.Add(new File(name, SuperBlock.GetFreeINode())); return true; } private bool SetWorkCatalog(string path) { if (path != "/") { if (path[0] == '/') { string[] st = path.Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries); SetSelectedCatalog(SuperBlock.FirstBlock, st, 0);


98 } else { string[] st = path.Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries); SetSelectedCatalog(_currentBlock, st, 0); } } else { _newBlock = SuperBlock.FirstBlock; } if (_newBlock != _currentBlock) { return true; } return false; } private void SetSelectedCatalog(Directory dir, string[] st, int step) { if (step < st.Length) { foreach (Block item in dir.Childrens) { if (item is Directory) { var temp = (Directory) item; if (step == (st.Length - 1) /*item.Name == st[p]*/) { if (item.Name == st[step]) { _newBlock = temp; return; } } else { SetSelectedCatalog(temp, st, step + 1); if (_newBlock != _currentBlock) { break; } } } } } } public string[] SayHello() { return SuperBlock.SayHello(); } internal void DeleteInstance() { _instance = new Unix(); } } }

////======== SuperBlock.cs ========///


99

using using using using using

System; System.Collections.Generic; System.Linq; System.Reflection; System.Windows.Forms;

namespace UNIX_FileSystem_Emulator.Classes { [Serializable] public class CSuperBlock { private readonly string _header; private readonly int _node; private readonly string _version; public int BlockSize; public DataBlock[] Blocks; public int CountOfFreeBlocks; public int CountOfMount; public Directory FirstBlock; public int MaxSizeOfImage; public string Name; private DateTime _data; public CSuperBlock(string name, int sizeOfImage, int sizeOfBlock) { MaxSizeOfImage = sizeOfImage; CountOfFreeBlocks = sizeOfImage/sizeOfBlock; BlockSize = sizeOfBlock; _header = "UNIX FILE SYSTEM EMULATOR"; Name = name; _node = 1; _version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); FirstBlock = new Directory("/", 2); CreateFileSystem(); CountOfMount = 0; _data = DateTime.Now; Blocks = new DataBlock[CountOfFreeBlocks]; for (int i = 0; i < Blocks.Length; i++) { Blocks[i] = new DataBlock(sizeOfBlock); } } public int GetSize() { return _header.Length + _version.Length + Unix.Instance.SuperBlock.Blocks.Length*Unix.Instance.SuperBlock.BlockSize + sizeof (int)*2 + Name.Length; } public string[] SayHello() { return new[] { "Добро пожаловать", _header + " - " + Name, "Версия эмулятора " + _version, "Образ создан " + _data.ToString(), "Количество монтирований: " + CountOfMount }; }


100 public string[] SayHello(char ch) { return new[] { "Название образа: " + _header, "Версия эмулятора " + _version, "Образ создан " + _data.ToString(), "Количество монтирований: " + CountOfMount, "Размер образа: " + GetSize() + " байт", "Свободно : " + GetFreeSize() + " байт", "Занято: " + (GetSize() GetFreeSize()) + " байт", "Место сохранения: " + Application.StartupPath + "\\" + Name + ".uimg" }; } private void CreateFileSystem() { var folders = new[] {"bin", "include", "lib", "local", "sbin", "share"}; foreach (string folder in folders) { FirstBlock.Childrens.Add(new Directory(folder, GetFreeINode())); } folders = new[] {"lib", "run", "spool"}; foreach (string t in folders) { var d = (Directory) FirstBlock.Childrens[1]; d.Childrens.Add(new Directory(t, GetFreeINode())); } } public int GetFreeINode() { int free = -1; var nodes = new List<int> {_node}; FindNodes(FirstBlock, nodes); for (int i = 0; i < MaxSizeOfImage/BlockSize; i++) { if (!nodes.Contains(i)) { free = i; break; } } return free; } private static void FindNodes(Block block, List<int> nodes) { nodes.Add(block.Node); if (block is Directory) { var d = (Directory) block; foreach (Block item in d.Childrens) { FindNodes(item, nodes); } } else { var f = (File) block; nodes.Add(f.Node); }


101 } public TreeNode GetChildrens() { var treeNodes = new TreeNode {Text = FirstBlock.Name}; FindChildrens(FirstBlock, treeNodes); return treeNodes; } private void FindChildrens(Block block, TreeNode treeNodes) { if (block is Directory) { var d = (Directory) block; foreach (Block data in d.Childrens) { if (data is Directory) { var dir = (Directory) data; treeNodes.Nodes.Add(new TreeNode("(d) " + dir.Node + " : " + dir.Name)); FindChildrens(dir, treeNodes.Nodes[treeNodes.Nodes.Count - 1]); } else { treeNodes.Nodes.Add(new TreeNode("(f) " + data.Node + " : " + data.Name)); } } } }

public int GetFreeBlockNumber() { for (int i = 0; i < Blocks.Length; i++) { if (!Blocks[i].IsBisy) return i; } return -1; } public int GetFreeSize() { int count = Blocks.Count(t => t.IsBisy == false);

return count*BlockSize; } } }


102 ПРИЛОЖЕНИЕ Г ЭКРАННЫЕ ФОРМЫ Г.1 Реализация многопоточности

Г.2 Реализация эмулятора файловой системы Г.2.1 Создание образа ФС


103 Г.2.2 Главное окно эмулятора и информация об образе

Г.2.3 Редактирование файлов


Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.