Околения компьютеров
Скачать 1.67 Mb.
|
контекст процесса. (в общем случае контекст процесса содержит информацию о текущем состоянии процесса, включая информацию о режимах работы процессора, содержимом регистровой памяти, используемой процессом, системной информации ОС, ассоциированной с данным процессом). Процессы, находящиеся в одном из состояний ожидания в своих контекстах содержат всю информацию, необходимую для продолжения выполнения - состояние процесса в момент прерывания (копии регистров, режимы ОП, настройки аппарата виртуальной памяти и т. д.). Соответственно при смене выполняемого процесса ОС осуществляет «перенастройку» внутренних ресурсов ЦП, происходит смена контекстов выполняемых процессов. На этапе выполнения процесса ОС обеспечивает возможность корректного взаимодействия процессов от передачи сигнальных воздействий от процесса к процессу до организации корректной работы с разделяемыми ресурсами. Итак, контекст процесса может состоять из: пользовательской составляющей – состояние программы, как совокупности машинных команд и данных, размещенных в ОЗУ; системной составляющей – содержимое регистров и режимов работы процессора, настройки аппарата защиты памяти, виртуальной памяти, принадлежащие процессу ресурсы (как физические, так и виртуальные). Типы процессов В различных системах используются различные трактовки определения термина процесс. Рассмотрим уточнение понятия процесса. Полновесные процессы - это процессы, выполняющиеся внутри защищенных участков памяти операционной системы, то есть имеющие собственные виртуальные адресные пространства для статических и динамических данных. В мультипрограммной среде управление такими процессами тесно связано с управлением и защитой памяти, поэтому переключение процессора с выполнения одного процесса на выполнение другого является достаточно дорогой операцией. В дальнейшем, используя термин процесс будем подразумевать полновесный процесс. Легковесные процессы, называемые еще как нити или сопрограммы, не имеют собственных защищенных областей памяти. Они работают в мультипрограммном режиме одновременно с активировавшей их задачей и используют ее виртуальное адресное пространство, в котором им при создании выделяется участок памяти под динамические данные (стек), то есть они могут обладать собственными локальными данными. Нить описывается как обычная функция, которая может использовать статические данные программы. Для одних операционных систем можно сказать, что нити являются некоторым аналогом процесса, а в других нити представляют собой части процессов. Таким образом, обобщая можно сказать – в любой операционной системе понятие «процесс» включает в себя следующее: исполняемый код; собственное адресное пространство, которое представляет собой совокупность виртуальных адресов, которые может использовать процесс; ресурсы системы, которые назначены процессу ОС; хотя бы одну выполняемую нить. При этом подчеркнем – понятие процесса может включать в себя понятие исполняемой нити, т. е. однонитевую организацию – «один процесс – одна нить». В данном случае понятие процесса жестко связано с понятием отдельной и недоступной для других процессов виртуальной памяти. С другой стороны, в процессе может несколько нитей, т. е. процесс может представлять собой многонитевую организацию. Нить также имеет понятие контекста – это информация, которая необходима ОС для того, чтобы продолжить выполнение прерванной нити. Контекст нити содержит текущее состояние регистров, стеков и индивидуальной области памяти, которая используется подсистемами и библиотеками. Как видно, в данном случае характеристики нити во многом аналогичны характеристикам процесса. С точки зрения процесса, нить можно определить как независимый поток управления, выполняемый в контексте процесса. При этом каждая нить, в свою очередь, имеет свой собственный контекст. Принципы организации свопинга. Проблема планирования определяет эксплуатационные качества системы. Это планирование времени, памяти. Это организация стратегий очередей. Планирование дает тип ОС. Рассмотрим ОС разделения времени. ОС разделения времени может быть с разными квантами времени, от чего меняются качества работы ОС. Большой квант времени – выполняются много мелких программ; маленький квант времени – многопользовательский режим работы. В ОС реального времени должна быть гарантия обработки времени за некоторое время. Проблема организации свопинга. Мультипрограммные ОС используют свопинг. Элементом планирования является планирование свопинга. Пример: простейшая операционная система типа UNIX: полная откачка процесса в свопинговую память. Сейчас все делается по частям. Правила откачки: в контексте процесса была переменная p_time – время непрерывного размещения процесса в область свопинга и обратно. Сначала p_time обнулилась и считала время, сколько процесс находится в этой области. Затем по определению расписания в ОС запускалась функция обработки, которая анализировала область свопинга и выбирала процесс с максимальным p_time, затем система анализировала наличие свободной оперативной памяти. Если ее достаточно, то процесс в нее загружался, иначе операционная система смотрела процесс, который закрыт по обмену и имеет максимальный p_time, и его откачивала в область свопинга. Затем вновь анализ оперативной памяти, если недостаточно, то далее анализировались процессы в оперативной памяти, затем отыскивался процесс с максимальным p_time и освобождал память. Он мешал в последнюю очередь тем процессам, которые нормально читались, однако мешал процессу в обмене. Это лишает ОС возможности сразу закончить обмен. Это простейшая схема. БИЛЕТ 23 Процесс в Unix Определение процесса. Контекст В любой системе, оперирующей понятием процесс, существует системно- ориентированное определение процесса (определение, учитывающее конкретные особенности данной ОС). С точки зрения Unix системно-ориентированное определение процесса: Рассмотрим данные определения процесса Unix. Процесс в ОС Unix – объект (не надо путать с объектом ООП!!!), зарегистрированный в таблице процессов Unix. Таблица процессов Каждый процесс характеризуется уникальным именем – идентификатором процесса (PID). PID – целое число от 0 до некоторого предельного значения, определяющего максимальное число процессов, существующих в системе одновременно. Будем использовать термины 0 й процесс, 1 й процесс, 125 й процесс, это означает, что речь идет о процессах с PID = 0, 1, 125. 0 й процесс в системе ассоциируется с работой ядра Unix. С точки зрения организации данных PID – номер строки в таблице, в которой размещена запись о процессе. Контекст процесса Содержимое записи таблицы процессов позволяет получить контекст процесса (часть данных контекста размещается непосредственно в записи таблицы процессов, на оставшуюся часть контекста имеются прямые или косвенные ссылки, также размещенные в записи таблицы процессов). С точки зрения логической структуры контекст процесса Unix состоит из: пользовательской составляющей или тела процесса (иногда используется пользовательский контекст) аппаратной составляющей (иногда используется аппаратный контекст) системной составляющей ОС Unix (иногда – системный контекст) Иногда два последних компонента объединяют, в этом случае используется термин общесистемная составляющая контекста. Объект, зарегистрированный в таблице процессов ОС Объект, порожденный системным вызовом fork() Процесс Тело процесса состоит из сегмента кода и сегмента данных. Сегмент кода содержит машинные команды и неизменяемые константы соответствующей процессу программы. Сегмент данных – содержит данные, динамически изменяемые в ходе выполнения кода процесса. Сегмент данных содержит область статических переменных, область разделяемой с другими процессами памяти, а также область стека (обычно эта область служит основой для организации автоматических переменных, передачи параметров в функции, организацию динамической памяти). Некоторые современные ОС имеют возможность разделения единого сегмента кода между разными процессами. Тем самым достигается экономия памяти в случаях одновременного выполнения идентичных процессов. Например, при функционировании терминального класса одновременно могут быть сформированы несколько копий текстового редактора. В этом случае сегмент кода у всех процессов, соответствующих редакторам, будет единый, а сегменты данных будут у каждого процесса свои. Следует отметить, что при использовании динамически загружаемых библиотек возможно разделение сегмента кода на неизменную часть, которая может разделяться между процессами и часть, соответствующую изменяемому в динамике коду подгружаемых программ. Аппаратная составляющая содержит все регистры и аппаратные таблицы ЦП, используемые активным или исполняемым процессом (счетчик команд, регистр состояния процессора, аппарат виртуальной памяти, регистры общего назначения и т. д.). Обращаем внимание, что аппаратная составляющая имеет смысл только для процессов, находящихся в состоянии выполнения. Для процессов, находящихся в других состояниях содержимое составляющей не определено. Системная составляющая. В системной составляющей контекста процесса содержатся различные атрибуты процесса, такие как: - идентификатор родительского процесса; - текущее состояние процесса; - приоритет процесса; - реальный идентификатор пользователя-владельца (идентификатор пользователя, сформировавшего процесс); - эффективный идентификатор пользователя-владельца (идентификатор пользователя, по которому определяются права доступа процесса к файловой системе); - реальный идентификатор группы, к которой принадлежит владелец (идентификатор группы к которой принадлежит пользователь, сформировавший процесс); - эффективный идентификатор группы, к которой принадлежит владелец (идентификатор группы «эффективного» пользователя, по которому определяются права доступа процесса к файловой системе); - список областей памяти; - таблица открытых файлов процесса; - информация о том, какая реакция установлена на тот или иной сигнал (аппарат сигналов позволяет передавать воздействия от ядра системы процессу и от процесса к процессу); - информация о сигналах, ожидающих доставки в данный процесс; - сохраненные значения аппаратной составляющей (когда выполнение процесса приостановлено). Рассмотрим второе определение процесса Unix. Процесс в ОС Unix – это объект, порожденный системным вызовом fork(). Данный системный вызов является единственным стандартным средством порождения процессов в системе Unix. Ниже рассмотрим возможности данного системного вызова подробнее. Аппарат системных вызов в OC UNIX. Привилегированный и обычный режим(есть набор инструкций, доступный только из привил.)Чтобы работать в с ресурсами ВС – переход в привел. Системные вызовы, предоставляемые ОС UNIX. К интересующим нас вызовам относятся вызовы - для создания процесса; - для организации ввода вывода; - для решения задач управления; - для операции координации процессов; - для установки параметров системы. Отметим некоторые общие моменты, связанные с работой системных вызовов. Большая часть системных вызовов определены как функции, возвращающие целое значение, при этом при нормальном завершении системный вызов возвращает 0, а при неудачном завершении -1 4 . При этом код ошибки можно выяснить, анализируя значение внешней переменной errno, определенной в заголовочном файле В случае, если выполнение системного вызова прервано сигналом, поведение ОС зависит от конкретной реализации. Например, в BSD UNIX ядро автоматически перезапускает системный вызов после его прерывания сигналом, и таким образом, внешне никакого различия с нормальным выполнением системного вызова нет. Стандарт POSIX допускает и вариант, когда системный вызов не перезапускается, при этом системный вызов вернет –1, а в переменной errno устанавливается значение EINTR, сигнализирующее о данной ситуации. 4 БИЛЕТ 24 Базовые средства организации и управления процессами Для порождения новых процессов в UNIX существует единая схема, с помощью которой создаются все процессы, существующие в работающем экземпляре ОС UNIX, за исключением первых двух процессов (0-го и 1-го). Для создания нового процесса в операционной системе UNIX используется системный вызов fork(), в результате в таблицу процессов заносится новая запись, и порожденный процесс получает свой уникальный идентификатор. Для нового процесса создается контекст, большая часть содержимого которого идентична контексту родительского процесса, в частности, тело порожденного процесса содержит копии сегментов кода и данных его родителя. Сыновний процесс наследует от родительского процесса: окружение - при формировании процесса ему передается некоторый набор параметров-переменных, используя которые, процесс может взаимодействовать с операционным окружением (интерпретатором команд и т.д.); файлы, открытые в процессе-отце, за исключением тех, которым было запрещено передаваться процессам-потомкам с помощью задания специального параметра при открытии. (Речь идет о том, что в системе при открытии файла с файлом ассоциируется некоторый атрибут, который определяет правила передачи этого открытого файла сыновним процессам. По умолчанию открытые в «отце» файлы можно передавать «потомкам», но можно изменить значение этого параметра и блокировать передачу открытых в процессе-отце файлов.); способы обработки сигналов; разрешение переустановки эффективного идентификатора пользователя; разделяемые ресурсы процесса-отца; текущий рабочий каталог и домашний каталоги и т.д. По завершении системного вызова fork() каждый из процессов – родительский и порожденный – получив управление, продолжат выполнение с одной и той же инструкции одной и той же программы, а именно с той точки, где происходит возврат из системного вызова fork(). Вызов fork() в случае удачного завершения возвращает сыновнему процессу значение 0, а родительскому PID порожденного процесса. Это принципиально важно для различения сыновнего и родительского процессов, так как сегменты кода у них идентичны. Таким образом, у программиста имеется возможность разделить путь выполнения инструкций в этих процессах. В случае неудачного завершения, т.е. если сыновний процесс не был порожден, системный вызов fork() возвращает –1, код ошибки устанавливается в переменной errno. Пример. Программа создает два процесса – процесс-предок распечатывает заглавные буквы, а процесс-потомок строчные. int main(int argc, char **argv) { char ch, first, last; int pid; if((pid=fork())>0) { /*процесс-предок*/ first =’A’; last =’Z’; } else { /*процесс-потомок*/ first =’a’; last =’z’; } for (ch = first; ch <= last; ch++) { write(1,&ch,1); } _exit(0); } Механизм замены тела процесса. Семейство системных вызовов exec() производит замену тела вызывающего процесса, после чего данный процесс начинает выполнять другую программу, передавая управление на точку ее входа. Возврат к первоначальной программе происходит только в случае ошибки при обращении к exec() , т.е. если фактической замены тела процесса не произошло. Заметим, что выполнение “нового” тела происходит в рамках уже существующего процесса, т.е. после вызова exec() сохраняется идентификатор процесса, и идентификатор родительского процесса, таблица дескрипторов файлов, приоритет, и большая часть других атрибутов процесса. Фактически происходит замена сегмента кода и сегмента данных. Изменяются следующие атрибуты процесса: - режимы обработки сигналов: для сигналов, которые перехватывались, после замены тела процесса будет установлена обработка по умолчанию, т.к. в новой программе могут отсутствовать указанные функции- обработчики сигналов; - эффективные идентификаторы владельца и группы могут измениться, если для новой выполняемой программы установлен s-бит - перед началом выполнения новой программы могут быть закрыты некоторые файлы, ранее открытые в процессе. Это касается тех файлов, для которых при помощи системного вызова fcntl() был установлен флаг close-on-exec. Соответствующие файловые дескрипторы будут помечены как свободные. Ниже представлены прототипы функций семейства exec(): #include **env); int execv(const char *path, const char **arg); int execvp(const char *file, const char **arg); int execve(const char *path, const char **arg, const char **env); Первый параметр во всех вызовах задает имя файла программы, подлежащей исполнению. Этот файл должен быть исполняемым файлом и пользователь- владелец процесса должен иметь право на исполнение данного файла. Для функций с суффиксом «p» в названии имя файла может быть кратким, при этом при поиске нужного файла будет использоваться переменная окружения PATH. Далее передаются аргументы командной строки для вновь запускаемой программы, которые отобразятся в ее массив argv – в виде списка аргументов переменной длины для функций с суффиксом «l» либо в виде вектора строк для функций с суффиксом «v». В любом случае, в списке аргументов должно присутствовать как минимум 2 аргумента: имя программы, которое отобразится в элемент argv[0], и значение NULL, завершающее список. В функциях с суффиксом «e» имеется также дополнительный аргумент, описывающий переменные окружения для вновь запускаемой программы – это массив строк вида name=value, завершенный значением NULL. |