Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Создание процессов и управление ими
Процесс создается из другого процесса с помощью системного вызова fork (). Когда процесс вызывает f ork(), мы можем сказать, что процесс порождает (spawned) новый процесс. Новый процесс считается дочерним процессом (child), а первый считается родительским процессом (parent). Каждый процесс имеет родителя, за исключением процесса init. Все процессы, порожденные процессом init, запускаются во время загрузки системы. Это описано в следующих разделах.
В результате такой модели дочерних/родительских процессов система образует дерево процессов, описывающее характер отношений между запущенными процессами. Рис. 1.3 иллюстрирует такое дерево процессов. Глава 1 • Обзор После создания дочернего процесса родительскому процессу может понадобиться узнать, когда он будет завершен. Системный вызов wait () используется для приостановки родительского процесса до тех пор, пока дочерний процесс не завершится. Процесс может заменить себя другим процессом. Это можно сделать, например, с помощью функции mingetty (), описанной ранее. Когда пользователю требуется доступ в систему, функция mingetty () запрашивает его пользовательское имя и заменяет себя процессом, выполняющим login (), в который в качестве параметра передается имя пользователя. Эта замена осуществляется с помощью вызова одного из системных вызовов exec (). 1.9.4.2 ID процесса Каждый процесс обладает уникальным идентификатором, называемым process ID (PID). PID - это неотрицательное целое число. Идентификаторы процессов выделяются в ин-крементной последовательности по мере создания процессов. По достижении максимального значения PID оно обнуляется и РГО начинают выделяться с наименьшего доступного числа, большего 1. Существует два специальных процесса: процесс 0 и процесс I1. Процесс 0 - это процесс, отвечающий за инициализацию и запуск процесса 1, который также известен как процесс init. Все процессы в запущенной системе Linux являются потомками процесса 1. После выполнения процесса 0 процесс init попадает в холостой цикл. Гл. 8, «Загрузка ядра», описывает этот процесс в разделе «Начало: start_kernel()». Для идентификации процесса используются два системных вызова. Системный вызов getpid () возвращает РГО текущего процесса, а системный вызов getppid() возвращает РГО родителя этого процесса. 1.9.4.3 Группы процессов Процесс может быть членом группы процессов, использующих один групповой ID. Группа процессов помогает образовывать наборы процессов. Это может потребоваться, например, если вы хотите быть уверенным, что несвязанные другим образом процессы получают сигнал kill в одно и то же время. Процесс, РГО которого идентичен ГО группы, считается лидером группы. ГО группы процессов можно манипулировать с помощью системных вызовов getpgidO и setpgidO, которые возвращают и устанавливают ГО группы процессов для указанных процессов соответственно. 1.9.4.4 Состояния процесса Процессы могут находиться в различных состояниях в зависимости от планировщика и доступности требуемых процессу системных ресурсов. Процесс может быть в запущенном (runnable) состоянии, если он в данный момент находится в очереди выполнения (run queue), структуре, которая содержит ссылки на процессы, которые в данный 1 Процесс с PID 0 и процесс с PID 1. Примеч. науч. ред. Обзор ядра Linux момент выполняются. Процесс может находиться в состоянии сна (sleep), если он ожидает освобождения ресурсов, занятых другим процессом, мертвым (dead), если он был убит, и покойным (defunct), или зомби (zombie), если процесс был завершен, прежде чем его родитель смог вызвать для него wait (). Описатель процесса У каждого процесса есть описатель, содержащий информацию об этом процессе. Описатель процесса содержит такую информацию, как состояние процесса, PID, пользовательскую команду на запуск и т. д. Эту информацию можно просмотреть с помощью вызова ps (состояние процесса). Вызов ps выводит нечто наподобие следующего:
root 10? S< [aio/0] root 2026? Ss /sbin/syslogd -a /var/lib/ntp/dev/log root 2029? Ss /sbin/klogd -c 1 -2 -x root 3324 tty2 Ss+ /sbin/mingetty tty2 root 332 5 tty3 Ss+ /sbin/mingetty tty3 root 332 6 tty4 Ss+ /sbin/mingetty tty4 root 3327 tty5 Ss+ /sbin/mingetty tty5 root 3328 tty6 Ss+ /sbin/mingetty tty6 root 3329 ttySO Ss+ /sbin/agetty -L 9600 ttySO vtl02 root 14914? Ss sshd: root@pts/0 root 14917 pts/0 Ss -bash root 17682 pts/0 R+ ps aux root 17683 pts/0 R+ more Список информации о процессах показывает, что процесс с PID 1 - это процесс init. Также в этом списке можно увидеть программы mingetty () и agetty (), ожидающие ввода от виртуального и параллельного терминалов соответственно. Обратите внимание, что они являются детьми предыдущих. И наконец, в списке можно увидеть сессию bash, в которой была использована команда ps aux | more. Заметьте, что |, которое используется для обозначения канала, - само не является процессом. Вспомните, что мы говорили о том, что каналы обеспечивают общение между процессами. В данном случае два процесса - это ps aux и more. Как вы можете видеть, колонка STAT означает состояние процесса, где S означает спящий процесс, a R запущенный или запускаемый процесс. Глава 1 • Обзор Приоритет процесса В однопроцессорных компьютерах мы можем выполнять в каждый момент времени только один процесс. Процессам назначаются приоритеты, и они борются друг с другом за время выполнения. Приоритет динамически изменяется ядром на основе того, сколько процессов в текущий момент запущено и каким приоритетом они до этого обладали. Процессу выделяется квант времени (timeslice) для выполнения, после которого планировщик заменяет его другим процессом, как будет описано ниже. Сначала выполняются процессы с наивысшим приоритетом, а затем все остальные. Пользователь может устанавливать приоритеты процессов с помощью вызова nice (). Этот вызов создает процессу преимущество перед другими, определяя, сколько процессов должны его подождать. Наивысший приоритет обозначается отрицательным числом, а наименьший - положительным. Чем больший приоритет передается nice, тем большему числу процессов придется подождать. Системные вызовы Системные вызовы - это основной механизм, с помощью которого пользовательские программы общаются с ядром. Обычно системные вызовы применяют внутренние вызовы библиотек, устанавливающие регистры и данные для каждого системного вызова, необходимые для его выполнения. Пользовательские программы связываются с библиотекой с помощью определенных механизмов и делают запрос ядру. Обычно системные вызовы обращены к одной из существующих подсистем. Это значит, что пользовательское пространство с помощью этого вызова может взаимодействовать с подсистемой из пространства ядра. Например, файлы требуют специального фай-лоидентифицирующего системного вызова и процессы выполняют соответствующий системный вызов. На протяжении этой книги мы рассмотрим системные вызовы, связанные с различными подсистемами ядра. Например, когда мы будем говорить о файловой системе, мы рассмотрим системные вызовы read(), write (), ореп() и close (). Так вы сможете увидеть, как реализована файловая система и как она управляется с помощью ядра. Планировщик Linux Планировщик Linux выполняет задачу передачи управления от одного процесса другому. За исключением процесса, имеющего преимущество ядра, в Linux 2.6 каждый процесс, включая ядро, может быть прерван практически в любой момент, а управление передано новому процессу. Например, когда происходит прерывание, Linux должен прервать выполнение текущего процесса и обработать прерывание. Дополнительно в многозадачной операционной системе, такой, как Linux, нужно убедиться, что ни один из процессов не занимает процессор слишком долго. Планировщик отвечает за обе эти задачи: с одной стороны, он заме- 1.10 Переносимость и архитектурные зависимости Популярное:
|
Последнее изменение этой страницы: 2016-03-25; Просмотров: 638; Нарушение авторского права страницы