русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Тема3,4,5: процессы и потоки ОС Linux


Дата добавления: 2013-12-23; просмотров: 3265; Нарушение авторских прав


1*. Реализация процессов в ОС Linux

Основными активными сущностями в ос Linux являются процессы. Процессы в Linux - классические, последовательные процессы. Каждый процесс выполняет одну программу и изначально получает один поток управления. У процесса есть один счетчик команд, который отслеживает следующую исполняемую команду. Linux позволяет процессу создавать дополнительные потоки. Также Linux представляет собой многозадачную систему, так, что несколько независимых процессов могут работать одновременно. У каждого процесса в Linux есть пользовательская часть, в которой работает программа пользователя, однако, когда один из потоков делает системный вызов, то происходит эмулированное прерывание с переключением в режим ядра. После этого поток начинает работу в контексте ядра с другой картой памяти, своим стеком ядра, счетчиком команд в режиме ядра и полным доступом ко всем ресурсам машины. Ядро ОC Linux внутренним образом представляет процессы как задачи при помощи структуры задач task_struct. Процесс с одним потоком представляется одной структурой задач, а многопоточный процесс будет иметь по одной структуре задачи для каждого из потоков пользовательского уровня. Само ядро является многопоточным и имеет потоки уровня ядра, которые не связаны ни с какими пользовательскими процессами и выполняют код ядра. Для каждого процесса в памяти находится его дескриптор типа task_struct. Он содержит важную информацию, необходимую ядру для управления всеми процессами. Дескриптор процесса создается при создании процесса. Для совместимости с другими системами unix процессы в Linux идентифицируются при помощи идентификатора процесса PID (Process Identifier). Ядро организует все процессы в двунаправленный список структур задач. Информация в дескрипторе процесса подразделяется на следующие категории:



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

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

3) Сигналы (маски, указывающие, какие сигналы перехватываются, какие временно заблокированы, и какие находятся в процессе доставки).

4) Машинные регистры. Когда происходит эмулированное прерывание в ядро, то машинные регистры сохраняются здесь

5) Состояние системного вызова (здесь хранится информация о текущем системном вызове)

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

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

8) Стек ядра (фиксированный стек для использования той частью процесса, которая работает в режиме ядра)

9) Разное (текущее состояние процесса, ожидаемое процессом событие, PID процесса, идентификаторы родительского процесса, группы)

2*. Взаимодействие процессов

В системе Linux процессы могут общаться друг с другом с помощью следующих структур:

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

Сигналы (signals) – процессы общаются при помощи программных прерываний. Процессы могут сообщить системе, какие действия следует предпринимать, когда придет сигнал: проигнорировать сигнал, перехватить его, позволить сигналу убить процесс.

SIGABRT – посылается, чтобы прервать процесс и создать дамп памяти

SIGFPE – произошла ошибка при выполнении операции с плавающей точкой

SIGILL – пользователь нажал клавишу delete, чтобы прервать процесс

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

3*. Механизмы создания нового процесса. Системный вызов fork созпдает … называемого родительским процессом (parent process), новый процесс называется дочерним процессом (child process). У родительского и дочернего процесса есть свои собственные образы памяти. Если впоследствии, родительский процесс изменяет свои переменные, то эти изменения остаются невидимыми для дочернего процесса. Сразу после выполнения системного вызова fork, значения всех соответствующих переменных в обоих процессах одинаковы, но после копирования всего адресного пространства родителя, последующие изменения в одном процессе не влияют на другой. Системный вызов fork возвращает дочернему процессу число 0, а родительскому – отличный от нуля PID дочернего процесса. Оба процесса проверяют возвращаемое значение и действуют соответственно. Открытые файлы используются родительскими и дочерними процессами совместно. Это значит, что, если какой-либо файл был открыт в родительском процессе, до выполнения системного вызова fork, то он остается открытым в обоих процессах. Изменения, произведенные с этим файлом любым из процессов видны другому. Если дочерний процесс желает узнать свой идентификатор, то он может воспользоваться системным вызовом getpid. Например, когда дочерний процесс завершается, его родитель получает идентификатор только что завершившегося процесса.

Механизм создания процесса

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

(картинка в СОС ~756 с)

При вызове fork() происходит следующее:

1) Выделение структуры задач для потомка

2) Заполнение структуры задач потоком данными родителя

3) Выделение памяти для стека и области пользователя дочернего процесса

4) Заполнение области пользователя дочернего процесса

5) Выделение идентификатора для дочернего процесса

6) Настройка дочернего процесса на использование программы родительского процесса

7) Копирование таблицы страниц для данных и стека

8) Настройка совместного использования открытых файлов

9) Копирование регистров родительского процесса в дочерний процесс

 

При системном вызове exec() происходит следующее:

1) Поиск исполняемого файла

2) Проверка разрешения на выполнение

3) Чтение и проверка заголовка

4) Копирование аргументов, среды в ядро

5) Освобождение нового адресного пространства

6) Копирование аргументов среды в стек

7) Сбрасывание сигнала

8) Инициализация регистров

Когда выполняется системный вызов fork(), вызывающий процесс выполняет эмулированное прерывание в ядро и создает структуру задачи. Большая часть содержимого дескриптора процесса заполняется значениями из дескриптора родителя, затем Linux ищет доступный идентификатор и обновляет элемент хэш-таблицы идентификаторов, чтобы там был указатель на новую структуру задачи. Далее система выделяет дочернему процессу его собственные таблицы страниц, но эти таблицы указывают на страницы родительского процесса, помеченного, как доступные только для чтения. Когда дочерний процесс пытается писать в такую страницу, происходит нарушение защиты. Ядро видит это и выделяет дочернему процессу новую копию этой страницы, которую помечает как доступную для чтения и для записи. Таким образом копируются только те страницы, в которые дочерний процесс пишет. Такой механизм называется копированием при записи. После того, как дочерний процесс начинает работу, его код делает системный вызов exec(), задавая имя команды в качестве параметра, при этом ядро находит и проверяет исполняемый файл, копирует в ядро аргументы и освобождает старое адресное пространство. Далее записывается новое адресное пространство. Сигналы сбрасываются, а все регистры устанавливаются в 0. После этого программа готова к работе.

4* Реализация потоков в ОС Linux

В 2000 году в Linux был введен новый системный вызов clone, который размыл отличия между процессами и потоками

Clone(function, stack_ptr, sharing-flags, arf);

Вызов clone создает новый поток либо в новом процессе, либо в текущем, все зависит от флага sharing-flags. Если новый поток находится в текущем процессе, то он совместно с существующими потоками использует адресное пространство и каждая запись в любой байт становится видна всем остальным потокам данного процесса. С другой стороны, если адресное пространство совместно не используется, то последующие записи новых потоков не будут видны старым. В обоих случаях новый поток начинает выполнение функции function с аргументом arg в качестве единственного параметра. Также в обоих случаях новый поток получает свой собственный стек, при этом указатель стека инициализируется параметром stack_ptr. Параметр sharing-flags представляет собой битовый массив. Каждый бит может быть установлен независимо от остальных, и каждый из них определят, копирует ли новый поток эту структуру данных или использует ее совместно с вызывающим потоком.

CLOVE_VM 1 - создать новый поток, 0 – создать новый процесс. Если этот бит установлен, но новый поток добавляется к старым. Если этот бит сброшен, то новый поток получает свое собственное адресное пространство.

CLONE_FS 1 – совместно используется рабочий каталог root и флаг umask. 0 – не использовать их совместно. Даже если у нового потока есть адресное пространство, старый и новый потоки будут использовать совместно общие каталоги.

CLONE_PID 1 – поток получает старый идентификатор. 0 – поток получает свой собственный идентификатор. Это свойство нужно при загрузке системы. Процессам пользователя не разрешается использовать это свойство

CLONE_PARENT 1 – новый поток имеет того же родителя, что и вызывающий, 0 – родителем нового потока является вызывающий.

CLONE_FILES 1 – используются общие дескрипторы файлов, если 0 – копируются

Чтобы сохранять совместимость с другим unix-системами, Linux разделяет структуры задач и процессы. Оба этих поля хранятся в структуре задач.



<== предыдущая лекция | следующая лекция ==>
Тема 2: Структура ядра ОС Linux. | Тема 7: Планирование в Linux


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.005 сек.