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

Билеты по unix.

  1. Системные вызовы в Unix. Errno. Отличие системных вызовов от обычных функций. Обработка ошибок системных вызовов с помощью функций perror и strerror.

Системный вызов — это обращение прикладной программы/функции к ядру операционной системы для выполнения какой-либо операции. Какие системные вызовы могут быть:

1)открыть файл (open, close) 2)записать пакет данных на диск ( read, write) 3)передать массив данных в сеть другому компьютеру. Errno — переменная целого типа. Каждый раз, когда системный вызов завершается ошибкой в эту переменную записывается код ошибки. Их всего 14. Если при системном вызове ошибок не было, то она остается без изменения. В современных ОС переменной errno нет, но есть такой макрос ( из-за многопоточности). Поэтому пишут #include <errno.h >.

perror и strerror — функции для печати ошибки на поле ошибок, которые соответствуют текущему знаению errno.

Strerror: параметр — целое число, значение переменной errno. Возвращаемое значение:

Указатель на строку, содержащую описание ошибки, код которой указан в аргументе errcode.

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

  1. Создание процессов в Unix с помощью функции fork. Копирование при записи в виртуальную память. Прежде всего обрисуем общую схему возможностей пользователя, связанных с управлением процессами. Каждый процесс может образовать полностью идентичный подчиненный процесс с помощью системного вызова fork() и дожидаться окончания выполнения своих подчиненных процессов с помощью системного вызова wait. В заключение затронем еще одну важную тему, непосредственно связанную с управлением виртуальной памятью - копирование страниц при попытке записи (copy on write). При выполнении системного вызова fork() ОС UNIX образует процесс-потомок, являющийся полной копией своего предка. Тем не менее, у потомка своя собственная виртуальная память, и те сегменты, которые должны быть его частными сегментами, в принципе должны были бы полностью скопироваться. Однако, несмотря на то, что частные сегменты допускают доступ и по чтению, и по записи, ОС не знает, будет ли предок или потомок реально производить запись в каждую страницу таких сегментов. Поэтому было бы неразумно производить полное копирование частных сегментов во время выполнения системного вызова fork().

Поэтому в таких случаях используется техника копирования страниц при попытке записи. Несмотря на то, что в сегмент запись разрешена, для каждой его страницы устанавливается блокировка записи. Тем самым, во время попытки выполнения записи возникает прерывание по защите памяти, и ОС на основе анализа статуса соответствующего сегмента принимает решение о выделении новой страницы, копировании на нее содержимого оригинальной страницы и о включении этой новой страницы на место старой в виртуальную память либо процесса-предка, либо процесса-потомка (в зависимости от того, кто из них пытался писать). Чаще всего в потомке поcле системного вызова fork выполняется системный вызов exec, котоый замещает собой созд. Процесс. Описание Семейство функций exec... загружает и запускает другие программы, известные как "дочерние процессы. Если вызов функции exec... завершается успешно, "дочерний" процесс накладывается на "родительский" процесс; причем должно быть достаточно памяти для загрузки и выполнения "дочернего" процесса. pathname - это имя файла вызываемого "дочернего" процесса. Суффиксы l, v, p и e, добавляемые к имени семейства exec... обозначают, что данная функция будет работать с некоторыми особенностями:

p - определяет, что функция будет искать "дочернюю" программу в директориях, определяемых переменной PATH. Без суффикса p поиск будет производиться только в рабочем каталоге. Если параметр path не содержит маршрута, то поиск производится в текущей директории, а затем по маршрутaм, определяемым переменной окружения PATH.

l - показывает, что адресные указатели (arg0, arg1,..., argn) передаются, как отдельные аргументы. Обычно суффикс l употребляется, когда число передаваемых аргументов заранее вам известно.

v - показывает, что адресные указатели (arg[0], arg[1],...arg[n]) передаются, как массив указателей. Обычно, суффикс v используется, когда передаeтся переменное число аргументов.

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

Каждая функция семейства exec... должна иметь один из двух суффиксов, определяющих аргументы (либо l, либо v). Суффиксы определения маршрута доступа (PATH) и унаследования операционной среды (p и e) являются необязательными.

Каждый элемент указывает на символьную строку с нулевым окончанием формы: envvar = value , где envvar - имя переменной среды, а value- значение символьной строки, которая присваивается каждой переменной envvar. Последним элементом в массиве envp[] является адресный нуль NULL. Когда значением envp[0] является NULL, "дочерний" процесс наследует назначения среды "родительского" процесса. При вызове функции exec... любые открытые файлы остаются открытыми и в "дочернем" процессе.

При успешном завершении функции exec... не возвра щают никакого значения. При возникновении ошибки функции exec... возвращают значение -1, а глобальная переменная errno получает значение. Вот что делает ядро системы при выполнении системного вызова fork:

  1. Выделяет память под описатель нового процесса в таблице описателей процессов.

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

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

  4. Увеличивает счетчики открытия файлов (процесс-потомок автоматически наследует все открытые файлы своего родителя).

  5. Возвращает вновь образованный идентификатор процесса в точку возврата из системного вызова в процессе-предке и возвращает значение 0 в точке возврата в процессе-потомке. exec позволяет в любой процесс загрузить новый иcполняемый код(т.е. заменить содержание ВП процеса) exec не создает новых процессов

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

стр. 107 Робачевский

1 секция - секция кода(текста), машинные команды и константы

2 секция - секция данных: переменные, которым присвоены начальные значения инициализированные статические или внешние переменные

3 секция - bss. В выполняемом файле обычно только размер этой секции. В bss хранятся

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

4 секция - точки входа, размеры секций и другая служебная информация Загрузка выполняемых файлов в текущий процесс - 189 Роб. Пользователь, транслируя исходный текст программы, создает исполняемый файл, который состоит из нескольких частей:

- набора "заголовков", описывающих атрибуты файла,

- текста программы, - представления на машинном языке данных, имеющих начальные значения при запуске программы на выполнение, и указания на то, сколько пространства памяти ядро системы выделит под неинициализированные данные, так называемые bss (ядро устанавливает их в 0 в момент запуска),

- других секций, таких как информация символических таблиц. Ядро загружает исполняемый файл в память при выполнении системной операции exec, при этом загруженный процесс состоит по меньшей мере из трех частей, так называемых областей: текста, данных и стека. Области текста и данных корреспондируют с секциями текста и bss-данных исполняемого файла, а область стека создается автоматически и ее размер динамически устанавливается ядром системы во время выполнения. Стек состоит из логических записей активации, помещаемых в стек при вызове функции и выталкиваемых из стека при возврате управления в вызвавшую процедуру; специальный регистр, именуемый указателем вершины стека, показывает текущую глубину стека. Запись активации включает параметры передаваемые функции, ее локальные переменные, а также данные, необходимые для восстановления предыдущей записи активации, в том числе значения счетчика команд и указателя вершины стека в момент вызова функции. Текст программы включает последовательности команд, управляющие увеличением стека, а ядро системы выделяет, если нужно, место под стек. Поскольку процесс в системе UNIX может выполняться в двух режимах, режиме ядра или режиме задачи, он пользуется в каждом из этих режимов отдельным стеком. Стек задачи содержит аргументы, локальные переменные и другую информацию относительно функций, выполняемых в режиме задачи. Стек ядра содержит записи активации для функций, выполняющихся в режиме ядра. Элементы функций и данных в стеке ядра соответствуют функциям и данным, относящимся к ядру, но не к программе пользователя, тем не менее, конструкция стека ядра подобна конструкции стека задачи. Стек ядра для процесса пуст, если процесс выполняется в режиме задачи.

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

Статические и динамически библиотеки.

Между стеком и кучей могут быть разделяемые библиотеки.

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

Динамические библиотеки - выполняемые функции несколькими точками входа, каждая

соответствует своей функции.

инамическая библиотека - библиотека, подключаемая к программе в момент выполнения. Это означает, что при создании библиотеки производится не только ее компиляция, но и линковка с другими, нужными ей, библиотеками (!). Динамические библиотеки полезны в случаях, если: - Важно не перекомпилировать всю программу, а только перекомпилировать ту часть, которая реализует определенные функции - тогда эти функции выносятся в динамическую библиотеку; - Важно использовать в программах на C библиотеки, подготовленные на C++ и при этом избежать лишних трудностей с линковкой программы; - Кроме того, динамические библиотеки позволяют экономить место на жестком диске и в оперативной памяти, если одна и таже библиотека используется несколькими программами.

PIC - код, который не зависит от расположения в ВП.

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

Если страница уже есть, он ее отобразит. Если нет, то загружает и отображает.

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

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

Обычно имеют расширение .so (shared object), располагается в /lib и /usr/lib

Преимущества и недостатки

Статические:

1) быстрее работают

2) большая переносимость

Динамические:

1) занимают меньше ВП

2) легче изменить поведение программы

При начале загрузки ОС большинство библиотек статические. Большинство программ

динамические.

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