Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

И 2 ПОКОЛЕНИЯ ОС. 3 страница



4) Включение и выключение устройств

СХЕМА РАБОТЫ УСТРОЙСТВА ВВОДА\ВЫВОДА.

Рассмотрим эту схему на примере запуска программы:

1) Пользователь инициализирует запуск какого-либо программного файла.

2) ОС на основании справочной информации, хранящейся в области корневого каталога и таблицы размещения файлов, находящейся в ОЗУ.

3) Затем ОС передает управление драйверу устройства ввода-вывода, в котором находится данный файл.

4) При помощи команд драйвера ОС переписывает файл с магнитного диска в буфер контроллера.

5) Когда буфер заполнен, то устройство ввода-вывода выдает сигнал-запрос на прерывание.

6) По этому сигналу ОС, используя информацию, находящуюся в таблице прерываний, запускает процесс обработки прерывания.

7) Обработчик прерывания переносит информацию из буфера контроллера в ОЗУ.

8) После того, как файл будет полностью скопирован в память, ОС полностью передаст ему управление.

НЕЗАВИСИМОЕ ОТ УСТРОЙСТВ ПО ВВОДА\ВЫВОДА.

В некоторых ОС могут существовать функции, связанные с вводом-выводом, не зависящим от конкретных устройств ввода-вывода. К таким функциям относятся:

1) Единообразный интерфейс для взаимодействия драйверов с ОС. Это набор привил, по которым создатели драйверов должны создавать свои программы для работы с конкретной ОС.

2) Буферизация. В некоторых ОС существует функция создания дополнительных буферов при работе с устройствами ввода-вывода. Буфер – это часть ОЗУ, которая резервируется для хранения информации, записанной или считанной с устройств ввода-вывода. Например, в ОС MS-DOS в файле CONFIG.SYS существует специальная команда BUFFERS, с помощью которой можно создать определенное число дисковых буферов. С помощью этих буферов ускоряется ввод-вывод информации с магнитный дисков.

3) Сообщения об ошибках. Эта часть ПО отвечает за индикацию сообщений об ошибках, связанных с вводом-выводом.

4) Захват и освобождение выделенных устройств. Эта часть ПО связана с распределением времени управления ОС различными устройствами.

ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ВВОДА\ВЫВОДА УРОВНЯ ПОЛЬЗОВАТЕЛЯ.

Хотя большая часть ПО ввода-вывода является частью ОС, однако некоторые функции, связанные с вводом-выводом, могут включаться в пользовательские программы. Такое ПО используется в многозадачных системах. Наиболее характерным примером такого ПО является Spooling.

Spooling – это предварительное накопление данных.

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

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

Спулинг используется не только для принтеров, например передачу файлов по сети осуществляет ДЕМОН. Чтобы посылать файл в другой компьютер, пользователь помещает его в каталог сетевого демона. Затем сетевой демон извлекает этот файл и посылает его по сети. Такая система работает в сервисе Интернета «Usenet News».

Вся эта система работает вне ОС.

СХЕМА РАБОТЫ ПО ВВОДА-ВЫВОДА.

ПО ввода-вывода уровня пользователя Spooling, обращение к ОС в вводе-выводе.
Устройство-независимое ПО операционной системы Обеспечение единого интерфейса для драйверов устройств, буферизация, вывод сообщения об ошибках.
Драйверы устройств Управление устройствами ввода-вывода при помощи команд, помещенных в регистры.
Обработчики прерываний Перенос информации из буфера устройства ввода-вывода в память и наоборот, передача управления драйверу.
Аппаратура ввода-вывода Выполнение операции ввода-вывода.

УПРАВЛЕНИЕ ПАМЯТЬЮ. ОСНОВНЫЕ ФУНКЦИИ.

Длительное время память представляла собой один из самых дорогостоящих ресурсов компьютера. Первые ПК имели память объемом 16-32 Кб и только Macintoch имел 64 Кб.

В настоящее время, благодаря успехам в развитии микроэлектроники ОЗУ достигла размеров 512 Мб - 1 Гб. В соответствии с принципом фон Неймана память имеет иерархическую структуру.

На верхней ступени иерархии находятся регистры микропроцессора, далее идет ОЗУ.

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

И на самой низкой ступени иерархии располагается внешняя память, которая имеет самый большой V, но минимальное быстродействие.

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

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

ПОНЯТИЕ О РАСПРЕДЕЛЕНИИ ПАМЯТИ.

Распределению памяти обычно подлежит вся часть ОЗУ, не занятая ОС. Обычно ОС располагается в самых младших адресах памяти, т.е. те, которые начинаются с 0.

ОС для управления памятью должна выполнять следующие функции:

1) Должна отслеживать участки свободной и занятой памяти.

2) Выделять память процессам и освобождать память при завершении процесса.

3) Вытеснять процессы из ОЗУ на магнитный диск в том случае, когда размера памяти не хватает для размещения всех процессов.

4) Возвращать процессы в ОЗУ, когда в ней освобождается место.

5) Настраивать адреса процессов на конкретную область физической памяти.

ТИПЫ АДРЕСОВ.

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

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

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

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

Практически никогда максимальный размер виртуального адресного пространства не совпадает с физическим V памяти, установленной на данном компьютере.

Физические адреса – это номера ячеек памяти, где в действительности будут расположены переменные и команды.

Превращение виртуальных адресов в физические может осуществляться 2 способами:

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

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

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

РАСПРЕДЕЛЕНИЕ ПАМЯТИ.


РАСПРЕДЕЛЕНИЕ ПАМЯТИ ФИКСИРОВАННЫМИ РАЗДЕЛАМИ.

Самым простым способом управления ОЗУ является разделение ее на несколько разделов фиксированной величины. Это может производиться вручную оператором во время старта системы, либо происходить автоматически во время запуска системы. При этом может быть 2 варианта распределения памяти при выполнении процесса:

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

2) Могут существовать очереди к разделам. В данном случае система управления памятью должна решать следующие задачи:

1. Сравнивать размер программы, поступающей на выполнение с V свободных разделов и выбирать подходящий для данной программы свободный раздел памяти.

2. Загружать программу в раздел и осуществлять настройку адресов.

Этот способ легко реализовывается, но имеет существенный недостаток:

1) Число одновременно выполняемых программ определяется числом разделов.

2) Даже если программа имеет небольшой объем, она все равно будет занимать целиком весь раздел, что приводит к неэффективному использованию памяти.

Такая система управления памятью использовалась в серии машин IBM 360. В современных ОС практически не используется.

РАСПРЕДЕЛЕНИЕ ПАМЯТИ РАЗДЕЛАМИ ПЕРЕМЕННОЙ ВЕЛИЧИНЫ.

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

Следовательно, в произвольный момент времени ОЗУ будет представлять из себя случайную последовательность свободных и занятых участков произвольного размера.

Задачи ОС при данном методе управления памятью:

1) Ведение таблиц свободных и занятых областей, в которых указываются начальные адреса и размеры участков памяти.

2) При поступлении новой задачи – анализ запроса, проверка таблицы свободных областей, выбор раздела, который достаточен для помещения этой задачи.

3) Загрузка задачи в выделенный не занятый раздел и корректировка работы таблиц свободных и занятых областей.

4) После завершения задачи – корректировка свободных и занятых областей.

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

1) В первый попавшийся раздел доступного размера.

2) В раздел, имеющий наименьший доступный размер.

3) В раздел, имеющий наибольший доступный размер.

Все они имеют свои плюсы и минусы по сравнению с методом управления памятью фиксированными разделами. Этот метод имеет более высокую гибкость, но и один недостаток: фрагментацию памяти.

Фрагментация памяти – образование несмежных свободных участков памяти небольшого V. В такие участки нельзя загрузить ни одну вновь поступающую программу.

РАСПРЕДЕЛЕНИЕ ПАМЯТИ ПЕРЕМЕЩАЮЩИМИСЯ РАЗДЕЛАМИ.

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

В этом случае в дополнение к тем функциям, которые выполняет ОС при управлении памятью разделами перемещающегося V, добавляется необходимость копировать содержимое разделов из одного места памяти в другое, корректируя при этом таблицы свободных и занятых областей. Такая процедура может производиться либо при каждом завершении задачи, либо когда для вновь поступившей задачи не хватает места. В 1 случае – меньше вычислительной работы при корректировке таблиц, во 2 случае – реже процедура сжатия.

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

ПОНЯТИЕ ВИРТУАЛЬНОЙ ПАМЯТИ.

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

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

Например, виртуальная память может быть представлена пользователю в таком V, который намного превосходит действительный V памяти, установленной на компьютере. Таким образом, виртуальная память – совокупность программно-аппаратных средств, позволяющий программистам писать программы, V которых превосходить физический V ОЗУ.

Виртуальная память должна выполнять следующие задачи:

1) Размещать данные в различных устройствах различного типа (часть в ОЗУ, часть на винчестере).

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

Все эти действия виртуальная память должна совершать без участия программиста (или пользователя).

Наиболее распространенными способами реализации виртуальной памяти являются:

1) Страничное распределение

2) Сегментное распределение

3) Странично-сегментное распределение

4) Свопинг

СТРАНИЧНОЕ РАСПРЕДЕЛЕНИЕ ПАМЯТИ.

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

Процесс 1
 
 
 
 
 
 
Процесс 2
 
 
 
 
 
 

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

Вся ОЗУ также делится на части того же размера, который носит название – физические страницы.

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

При загрузке процесса часть его виртуальных страниц помещается в ОЗУ, остальные – на диск. Смежные виртуальные станицы не обязательно должны располагаться в смежных физических страницах. При загрузке процесса ОС создает специальную информационную структуру – таблицу страниц процесса.

В эту таблицу входят номера виртуальных страниц и номера физических страниц, в которые загружаются виртуальные страницы.

Таблица станиц процесса
№ виртуальной страницы № физической страницы Управляющая информация
     
  ВП  
  ВП  
     
     

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

Кроме того, в таблице страниц хранится управляющая информация. К ней относится:

1) Была ли изменена страница

2) Признак выгруженности (некоторые страницы нельзя выгружать на магнитный диск)

3) Некоторые другие данные, которые формируют механизм виртуальной памяти.

При оптимизации очередного процесса в специальный регистр процессора загружается адрес таблицы данного процесса.

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

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

При этом используется несколько алгоритмов:

1) Выгружаются из памяти дольше всего не использующиеся страницы

2) Выгружается из памяти первая попавшаяся страница

3) Выгружается страница, к которой в последнее время было меньше всего обращений

В некоторых ОС имеется понятие рабочего множества страниц. Рабочее множество страниц определяется для каждого процесса и представляет из себя перечень страниц, которые наиболее часть используются и, поэтому должны постоянно находиться в ОЗУ.

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

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

Виртуальный адрес при страничной организации памяти может быть представлен в виде двоичного числа, состоящего из двух частей, одна из которых является номером виртуальной страницы процесса, а вторая – смещением в виртуальной странице. Учитывая то, что размер страницы равен 2k, смещение S может быть получено отделением k двоичных разрядов в двоичной записи виртуального адреса.

При каждом обращении к ОЗУ аппаратные средства ЭВМ выполняют следующие действия:

На основании начального адреса таблицы страниц (хранится в специальном регистре процессора), а также номера виртуальной страницы и длины записи в таблице страниц определяется адрес нужной записи в таблице. Из этой записи извлекается номер физической страницы. Физический адрес также будет состоять из двух двоичных чисел. Старшими разрядами физического адреса является номер физической страницы. К нему добавляется смещение, которое равно смещению виртуальной страницы. Т.к. V страницы равен 2k, то это позволяет при образовании физического адреса заменить операцию сложения операцией конкатенации (присоединения).

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

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

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

СЕГМЕНТНОЕ РАСПРЕДЕЛЕНИЕ ПАМЯТИ.

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

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

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

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

Во время загрузки процесса ОС также создает таблицу сегментов процесса, аналогичную таблице страниц.

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

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

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

При сегментной организации памяти виртуальный адрес, так же как и при страничной организации памяти состоит из двух двоичных чисел:

1) Номер сегмента

2) Смещение

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

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

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

СТРАНИЧНО-СЕГМЕНТНОЕ РАСПРЕДЕЛЕНИЕ ПАМЯТИ.

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

ОЗУ делится на физические страницы. Загрузка процесса выполняется ОС постранично, при этом часть страниц размещается в ОЗУ, а часть – на диске.

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

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

СВОПИНГ. КЕШ-ПАМЯТЬ.

СВОПИНГ.

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

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

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

КЕШ-ПАМЯТЬ.

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

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

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

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

Каждая запись в Кэш-памяти хранит следующую информацию:

1) Адрес данных в RAM

2) Данные

3) Управляющая информация

a. Признак модификации

b. Признак обращения к данным за некоторый последний отрезок времени.





Дата публикования: 2014-11-29; Прочитано: 172 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.021 с)...