Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
mtd_SPO_2013i.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
370.18 Кб
Скачать

2. Система электронной документации.

Для любой команды и установленного пакета существует электронное описание, вызываемое командой man (от английского термина "manual" -- руководство). Для многих пакетов, кроме man существует детализированное описание с примерами в виде обычных ASCII-файлов (часто имеющих суффикс .txt', просматриваемых, например, при помощи less, и HTML-файлов, имеющих суффикс html и просматриваемых произвольным браузером. Синтаксис команды просмотра руководства:

man [ -h ] [ -k | -f ] [секция] [тема]

наиболее важными являются опции:

-h -- краткий help по команде man;

-k -- поиск тем по ключевому слову или его части

-f -- поиск тем только по целому ключевому слову;

секция -- число от 1 до 9, задающее номер секции справочной системы.

тема -- наименование команды, системного вызова, библиотечной функции, ключевое слово для поиска;

Справочная система FreeBSD разделена на 9 секций:

1. Внешние команды; для справок по встроенным командам вызывается

описание соответствующего `shell', например `man bash'.

2. Системные вызовы.

3. Библиотечные функции (функции стандартной библиотеки языка C).

4. Специальные файлы.

5. Форматы файлов.

6. Игры.

7. Разное.

8. Команды и файлы системного администратора.

9. Документация для разработчиков ядра.

Тема – это либо имя искомого объекта: команды, системного вызова, библиотечной функции, и.т.д., либо ключевое слово в кратком описании объекта (при использовании опций -k, -f ).

Некоторые темы входят в несколько секций, например имеется команда sleep, описанная в секции 1, и библиотечная функция sleep, описанная в секции 3. Соответственно, для получения справки используется либо команда «man 1 sleep» , либо «man 3 sleep» . При выводе информации по теме, номер секции указывается в круглых скобках за наименованием темы.

Опции -f и -k позволяют найти все команды, в кратких описаниях которых содержится ключевое_слово, причем команда man -k ключевое_слово отбирает только те описания в которых оно встречается как полное отдельное слово, а команда man -k ключевое_слово дополнительно отбирает и те описания тем, в которых оно встречается как подстрока в слове, т.е. отбирается больше объектов. В обеих случаях выводятся только заголовки описаний, для которых найдено совпадение. Для команды man с ключами -f, -k существуют эквивалентные команды без ключей:

whatis эквивалентно man -f

apropos эквивалентно man -k

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

PAGER="less -F"

Теперь по умолчанию до конца сеанса работы для просмотра будет вызываться утилита less -F. При новом входе в систему эту команду придется повторить (еще раз набирать ее не нужно, вызывайте ее из history). В обоих утилитах more и less для завершения просмотра нужно нажимать q. Опция -F в обеспечивает автоматический выход из утилиты при небольшом числе строк просматриваемой информации, когда вся информация умещается на одном экране и не требуется пролистывание.

Примеры использования справочной системы:

whatis sleep -- поиск тем по ключевому слову sleep

Например, имя write имеют два совершенно различных объекта (совпадающие имена двух совершенно различных понятий в лингвистике называются омонимами). При вызове статьи документации омонимов обязательно нужно задавать в командной строке номер секции документации. Системный вызов write(2) выводит заданное количество байт из заданного буфера (т.е. переменной, содержащей строку, для которой задана максимальная длина) в объект, созданный предшествующим системным вызовом open и заданный дескриптором. Существует и утилита write(1) для переписки пользователей, работающих в системе в данный момент (имеющих терминальные сессии). Утилита write(1) позволяет вывести текст из одной сессии на терминал другой сессии. Сравните результаты команд:

man 1 write

# это write из секции (1) FreeBSD General Commands Manual

man 2 write

# это write из секции (2) FreeBSD System Calls Manual

Имя read также имеет два омонимических смысла. Системный вызов read (2) читает заданное число байт из объекта, созданного предшествующим системным вызовом open и заданного дескриптором в команда (built-in) read в оболочке bash (и в других оболочках также). Чтобы посмотреть ее полное описание нужно вызвать man bash и подогнать к описанию соответствующей builtin: /read , многократно нажимая продолжение поиска: n (Если проскочите, то поиск в обратном направлении N). В связи с частой встречаемостью слова read в английском языке и учитывая, что описания builtin в manual по bash идут в алфавитном порядке, быстрее будет искать с конца:

man bash

G # на конец руководства

?read # искать от конца - к началу руководства

n # следующая встречаемость

n

n

и т.д. , а если проскочите, то вернуться можно, нажимая N

Builtin read служит для присваивания переменным значений, вводимых с клавиатуры или из файла. Переменные могут быть ранее созданными переменными окружения или локальными или вообще создаваться как локальные переменные при вводе значения. Имена переменных задаются в строке вызова read. По умолчанию значения читаются из одной следующей вводимой из STDIN строки (либо из файлового дескриптора, заданного в опции -u дескриптор). Чтобы понять работу builtin read, достаточно сделать маленькое упражнение:

read AA BB CC # создать и ввести с клавиатуры значения

# переменных AA BB CC

111111 bbbbbbb cccc 444444

echo $AA # 111111 - вывод значения переменной AA

echo $BB # bbbbbbb - вывод значения переменной BB

echo $CC # cccc 444444 - вывод значения переменной СС

set | less # вывод всех переменных bash

(или `man -f sleep');

apropos sleep -- поиск тем по части ключевого слова `sleep';

(или `man -k sleep');

man 1 sleep -- описание команды `sleep';

man 3 sleep -- описание библиотечной функции 'sleep()';

man 2 nanosleep -- описание системного вызова nanosleep().

2. Исполняемый файл и инфраструктура процесса.

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

Текстовый исполняемый файл предполагает, что система имеет интерпретатор языка текстового исполняемого файла, под управлением которого будет выполняться программа. Большую часть кода в этом случае составляет код этого интерпретатора, размещенный в динамических библиотеках разделяемого доступа и таким образом являющийся общим разделяемым ресурсом для всех пользователей. Современный развитый язык (например, Perl) выполняет компиляцию и оптимизацию исходного кода текстового исполняемого файла всего за два прохода, но в результате компиляции создает не машинный код со связанными адресами, а объектный код, сохраняя его в оперативной памяти. Это не требует длительной многопроходной циклической обработки программы для связывания всех адресов переменных, подпрограмм, вызываемых библиотек, поэтому выполняется практически мгновенно. Это очень удобно для программистов, вносящих изменения в программу в период ее доводки, отладки и проверки, а также при модернизации, обновлении и добавлении новых функций в раннее разработанные программы, находящиеся в эксплуатации. Обеспечивается интерактивный цикл разработки программы одновременно с доводкой и уточнением алгоритма: после внесения минимального изменения в текст программы, производится ее пробный запуск и мгновенное получение результата измененной программы. Если программа имеет такой большой объем, что для создания бинарного исполняемого модуля традиционными компиляторами со связыванием адресов (например для языка С) время получения результата измененной программы составляет несколько часов, то в случае языка Perl это будет 1-2 секунды. Еще одним недостатком традиционных компиляторов является то, что полученный бинарный исполняемый файл в общем случае может выполняться только в той же версии и релизе операционной системы, в котором он компилировался.

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

На рис.1 показано как на основе файла с исходным текстом программы на

языке С и библиотек системы создается инфраструктура процесса. Компилятор gcc, получив эти вводные данные, производит бинарный исполняемый файл.

Рис.1 Получение исполняемого файла и инфраструктура процесса.

Системный вызов exec разложит части исполняемого файла в инфраструктуру, образованную системным вызовом fork и размещенную в виртуальном адресном пространстве дочернего процесса. Два элемента инфраструктуры процесса заслуживают особого внимания. Это структура proc , которая постоянно находится в резидентной памяти ядра и информация в ней постоянно нужна, от момента создания процесса до его завершения, она изображена на рис.1 одним блоком, детализация этой структуры показана на рис.2.

Совокупность структур proc всех процессов образует таблицу процессов системы в текущий момент времени. Остальные элементы инфраструктуры подразделяются на две части, доступные для изменения в двух режимах выполнения процесса: режиме задачи (user mode) и в режиме ядра (kernel mode). При выполнении в режиме ядра центральный процессор вычислительной системы переключается на привилегированный уровень, в котором доступны для выполнения любые инструкции из системы команд процессора. Когда процесс выполняется в режиме задачи, то центральный процессор работает на непривилегированном уровне, на котором ряд команд, связанных с системными функциями управления вычислительным процессом, недоступен (например, изменение регистров, связанных с управлением памятью, может производиться только в режиме ядра). Процессоры серии Intel имеют 2 уровня команд, начиная с системы команд i-386, с момента ее выпуска

Рис. 2. Управляющие структуры процесса

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

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

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

/usr/include/sys/proc.h

/usr/include/sys/user.h

Структура proc содержит следующие атрибуты процесса:

RUID

EUID

PPID

PGID

Идентификатор сеанса

Сигналы, ожидающие доставки

Текущий приоритет процесса

Состояние процесса (выполнение, приостановлен, сон и т.д.)

Код возврата, передаваемый родительскому процессу

Список областей памяти процесса

Массив записей таблицы страниц для `u-area'

Статистика: отдельно время выполнения в режиме задачи и в режиме ядра.

Структура `proc' является записью системной таблицы процессов, которая резидентно находится в ОП, таким образом для любого процесса в любом его состоянии структура `proc' -- всегда в ОП. Остальные данные образа процесса могут периодически перемещаться в область свопинга на диске в процессе страничного обмена. Структура `proc' выполняющегося в данный момент процесса адресуется системной переменной curproc. Всякий раз при переключении контекста происходит изменение значения переменной curproc, которая всегда указывает на структуру `proc' активного процесса (который выполняется и владеет процессором в данный момент). Контекстом называется совокупность данных на регистрах процессора которую нужно запомнить в u-area при передаче управления другому процессу, чтобы потом можно было продолжить процесс именно с этой точки, занеся эти данные на регистры.

Структура u-area содержит дополнительные данные о процессе, которые требуются ядру только во время выполнения процесса, т.е. когда он является активным. Структура u-area размещается в виртуальной памяти ядра и адресуется переменной u. В структуре u-area содержатся данные, используемые многими подсистемами ядра, например таблица файловых дескрипторов для всех открытых файлов процесса, сохраненные значения регистров, когда выполнение процесса приостановлено, указатели на vnode текущего (cdir) и корневого (rdir) директориев, которые также являются атрибутами процесса. Процесс не должен модифицировать эти данные, поэтому u-area защищена от доступа в режиме задачи. В режиме ядра используется не обычный стек процесса, а отдельный стек фиксированного размера, содержащийся в u-area – системный стек (для каждого процесса – cвой).

3. Жизненный цикл и состояния процесса.

Все блоки, состояний на схеме пронумерованы, поясним их содержание:

1. Процесс создан вызовом fork(2) он существует, но не готов к запуску.

2. Завершается дочерняя часть вызова fork(2) и переходит в состояние готов

Рис.3 Жизненный цикл и состояния процесса

к запуску (2). Это очередь процессов к ресурсу центрального процессора.

3. Выбранный планировщиком из очереди процесс переходит через состояние 3 где завершается переключение контекста в состояние 4 - выполнение в режиме задачи.

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

5. При ожидании доступа к занятому ресурсу, а также при выполнении команды sleep вызывается функция ядра sleep(), которая переводит процесс в состояние сна. При этом процесс освобождает все ресурсы, которые могут быть переданы следующему наиболее приоритетному процессу (у которого минимальное значение атрибута pri). Когда требуемый ресурс освобождается (либо истекает время, заданное в команде sleep), ядро пробуждает процесс, используя функцию wakeup() и помещает его в очередь на выполнение - готов к запуску (2).

Переключение контекста(context switch). Происходит при предоставлении вычислительных ресурсов очередному наиболее приоритетному процессу. Состояние (context) текущего процесса сохраняется (в его u_area) и управление передается новому процессу. Переключение контекста происходит при переходе текущего процесса в состояние сна (по внутренним причинам процесса), либо если в очереди на выполнение (в состоянии 2 - готов к запуску) оказывается более приоритетный процесс, чем выполняющийся. Рассмотрим переходы, обозначенные литерам A и B на рис.3:

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

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

- если процесс был прерван при переходе из режима ядра в режим задачи, либо если он только что был создан, то он немедленно переходит в режим задачи. (Невозможны пути fork() --> B --> A или A --> B --> A).

- если процесс был пробужден после сна, он продолжает выполняться в режиме ядра, завершая системный вызов. Возможно, после завершения системного вызова в момент перехода в режим задачи он будет прерван для переключения контекста по причине приоритета (возможен путь wakeup() --> B --> A) .

6. Для завершения процесс выполняет системный вызов exit() (внутренние причины), либо процесс завершается при получении соответствующего сигнала, обработчик которого предписывает снятие процесс. Ядро освобождает все ресурсы, принадлежавшие процессу и все структуры, кроме структуры proc, в которой содержится код возврата и статистика (время в режиме задачи и в режиме ядра). Эти данные должны быть прочитаны процессом-родителем. Это состояние называется зомби (Z), когда фактически процесса нет, осталась только его структура proc (т.е. запись в общесистемной таблице процессов). Процесс-родитель должен выполнить один из системных вызовов wait() для получения кода возврата, тогда будет уничтожена и эта последняя структура proc, т.е. процесс вычеркнут из системной таблицы процессов. Если процесс-родитель завершается раньше потомка, потомки передаются процессу `init', который никогда не завершается, он обработает код возврата и статистику выполнения процесса, таким образом процесс не застрянет в состоянии зомби.

7. Состояния 7,8 связаны с системой управления заданиями. Процесс выполняющийся или готовый к запуску может быть переведен в состояние 7 (остановлен) сигналом SIGSTOP. Этот сигнал посылается активному процессу с клавиатуры управляющего терминала при нажатии ^z, но может быть послан любому процессу с помощью системного вызова kill(2) и с помощью команды kill. Выполняющийся в фоновом режиме процесс может быть остановлен операционной системой при попытке запросить ввод с терминала - SIGTTIN, или при попытке вывести на терминал - SIGTTOU. При остановке выполняющегося процесса, если он находился в режиме задачи, он проходит через режим ядра, что необходимо для обработки реакции на сигналы и переключения контекста.

8. В состоянии сна процесс реагирует на сигнал SIGSTOP и переходит в состояние 8 – “остановлен в состоянии сна”.

Возобновление работы остановленного процесса производится сигналом SIGCONT, который может быть послан с помощью системного вызова kill(2) или команды kill, а также командами системы управления заданиями (что более всего и используется):

fg - продолжить выполнение в интерактивном режиме или

bg - продолжить выполнение в фоновом режиме.

При возобновлении работы из состояния остановлен (7) процесс переводится в состояние готов к запуску (2), а из состояния остановлен в состоянии сна (8) -- к продолжению сна (5).

При выводе информации о процессах командой ps состояния процесса обозначаются в колонке STAT следующими символами:

J – (Jail) процесс, выполняемый в jail -- системе с ограниченными правами.

R – (Ready) готов к выполнению или выполняется, состояния 2,3,4.

+ – текущий интерактивный процесс (3,4).

s – (session) процесс - лидер сессии.

S – (Sleep) состояние 5 (сон) менее 20 сек.

I – (Inactive) состояние 5 (сон) более 20 сек.

T – (Stop, Suspend) приостановленный процесс (7,8).

D – (Disk) процесс, ожидающий завершения операций с диском.

W – (Write) выгруженный на диск процесс.

E – (Exit) процесс находится в стадии завершения.

Z – (Zombie) процесс в состоянии зомби (6).

L – процесс, имеющий закрепленные в основной памяти страницы.

4 . Состояние сна.

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

процесс в состояние сна:

-- запуск операции ввода-вывода с диска;

-- ожидание выделения (или освобождения) буфера;

-- ожидание ввода или вывода на терминал;

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

-- в ОП отсутствует страница, к виртуальному адресу которой обратился процесс, поэтому необходим свопинг (страничный обмен).

Примеры упражнений на компьютере (используется команда sleep):

sleep 900

# интерактивный процесс -- спать 900 сек приглашения нет, терминал занят

^z

# остановить интерактивный процесс, создается задание [1], терминал освобождается и появляется приглашение. Следующие две команды выводят таблицу процессов владельца сессии и текущий список заданий, их нужно посылать после каждого запуска нового процесса или изменения состояния любого из существующих процессов. Просмотр процессов и заданий:

ps -O start,ppid,user

jobs –l

# для просмотра заданий можно послать односимвольный алиас j .

Задание образуется при остановке интерактивного процесса при помощи ^z. Также задание создается каждым процессом, запущенным в фоновом режиме. Для запуска процесса в фоновом режиме -- в конце командной строки нужно поставить символ &. Задания создаются и управляются текущим процессом оболочки, они нумеруются, начиная с 1. Если образовать группу заданий во вложенном вызове оболочки, то нельзя будет выйти из него (exit), пока не будут завершены все задания этой оболочки.

sleep 800 &

# Образовалось задание [2] – процесс который будет в состоянии сна 800 секунд в фоновом режиме (терминал свободен, на экране есть приглашение для ввода команды). Просмотреть процессы и задания, в колонке статуса процесса символы S (первые 20 секунд) или I (после 20 секунд) обозначают состояние сна, Т – состояние процесс приостановлен ( SUSPEND, в том числе и приостановлен в состоянии сна).

bg %1

# продолжить первый процесс в фоновом режиме. Просмотреть процессы и задания.

fg %2

# перевести процесс задания [2] из фонового в интерактивный режим. Терминал занят, приглашения нет

^z

# остановить интерактивный процесс. Просмотреть процессы и задания.

sleep 700 &

# Запустить фоновый процесс (3-й job). Просмотреть процессы и задания.

kill -STOP %1

# или вместо %1 задать PID процесса sleep 900, образующего 1-й job.

# Просмотреть процессы и задания. Убедиться, что процесс приостановлен.

# Просматривать процессы и задания после каждой из следующих трех команд. Убедиться, процессы заданий [2] [3] завершены, . процесса 1-го job-а возобновлен в фоновом режиме.

kill -TERM %3 # или задать вместо %3 PID процесса 3-го job-а

kill -KILL %2 # вместо %2 PID процесса 2-го job-а

kill -CONT %1 # вместо %1 PID процесса 1-го job-а

Даже если процесс был приостановлен из интерактивного режима нажатием ^z , sigCONT возобновит его в фоновом режиме, убедитесь в этом просматривая процессы и задания после каждой команды:

kill -INT %1

sleep 600

^z

kill -CONT %1

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]