Один из таких примеров — процедура регистрации. Процесс init запускает программу getty для каждого последовательного терминала или модема коммутируемой линии передачи, которые можно применять для регистрации. Эти процессы отображены в следующем выводе команды ps:
9619 tty2 Ss+ 0:00 /sbin/mingetty tty2
Процессы getty ждут работы на терминале, приглашая пользователя зарегистрироваться хорошо всем знакомой строкой, и затем передают управление программе регистрации, которая устанавливает окружение пользователя и в конце запускает сеанс командной оболочки. Когда пользовательский сеанс командной оболочки завершается, процесс init запускает новый процесс getty.
Как видите, способность запускать новые процессы и ждать их окончания — одна из основных характеристик системы. Позже в этой главе вы узнаете, как выполнять аналогичные задачи в ваших собственных программах с помощью системных вызовов fork, exec и wait.
Планирование процессов
В следующем примере вывода команды ps приведен элемент списка для самой команды ps.
21475 pts/2 R+ 0:00 ps ax
Эта строка означает, что процесс 21475 находится в состоянии выполнения (R) и выполняет он команду ps ах. Таким образом, процесс описан в своем собственном выводе! Индикатор состояния показывает только то, что программа готова к выполнению, а не то, что она обязательно выполняется в данный момент. На однопроцессорном компьютере в каждый момент времени может выполняться только один процесс, в то время как другие процессы ждут своего рабочего периода. Эти периоды, называемые квантами времени, очень короткие и создают впечатление одновременного выполнения программ. Опция R+ просто показывает, что данная программа — фоновая задача, не ждущая завершения других процессов или окончания ввода или вывода данных. Именно поэтому можно увидеть два таких процесса, приведенные в списке вывода команды ps. (Другой, часто встречающийся процесс, помечаемый как выполняющийся, — дисплейный сервер системы X.)
Ядро Linux применяет планировщик процессов для того, чтобы решить, какой процесс получит следующий квант времени. Решение принимается исходя из приоритета процесса (мы обсуждали приоритеты процессов в главе 4). Процессы с высоким приоритетом выполняются чаще, а другие, такие как низкоприоритетные фоновые задачи, — реже. В ОС Linux процессы не могут превысить выделенный им квант времени. Они преимущественно относятся к разным задачам, поэтому приостанавливаются и возобновляются без взаимодействия друг с другом. В более старых системах, например Windows 3.х, как правило, для возобновления других процессов требовалось явное согласие процесса.
В многозадачных системах, таких как Linux, несколько программ могут претендовать на один и тот же ресурс, поэтому программы с короткими рабочими циклами, прерывающиеся для ввода, считаются лучше ведущими себя, чем программы, прибирающие к рукам процессор для продолжительного вычисления какого-либо значения или непрерывных запросов к системе, касающихся готовности ввода данных. Хорошо ведущие себя программы называют nice-программами (привлекательными программами) и в известном смысле эту "привлекательность" можно измерить. Операционная система определяет приоритет процесса на основе значения "nice", по умолчанию равного 0, и поведения программы. Программы, выполняющиеся без пауз в течение долгих периодов, как правило, получают более низкие приоритеты. Программы, делающие паузы время от времени, например в ожидании ввода, получают награду. Это помогает сохранить отзывчивость программы, взаимодействующей с пользователем; пока она ждет какого-либо ввода от пользователя, система увеличивает ее приоритет, чтобы, когда программа будет готова возобновить выполнение, у нее был высокий приоритет. Задать значение nice для процесса можно с помощью команды nice, а изменить его — с помощью команды renice. Команда nice увеличивает на 10 значение nice процесса, присваивая ему более низкий приоритет. Просмотреть значения nice активных процессов можно с помощью опций -l или -f (для полного вывода) команды ps. Интересующие вас значения представлены в столбце NI (nice).
$ <b>ps -l</b>
F S UID PID PPID С PRI NI ADDR SZ WCHAN TTY TIME CMD
000 S 500 1259 1254 0 75 0 - 710 wait4 pts/2 00:00:00 bash
000 S 500 1262 1251 0 75 0 - 714 wait4 pts/1 00:00:00 bash
000 S 500 1313 1262 0 75 0 - 2762 schedu pts/1 00:00:00 emacs
000 S 500 1362 1262 2 80 0 - 789 schedu pts/1 00:00:00 oclook
000 R 500 1363 1262 0 81 0 - 782 - pts/1 00:00:00 ps
Как видно из списка, программа oclock выполняется (как процесс 1362) со значением nice по умолчанию. Если бы она была запущена командой
$ <b>nice oclock &</b>
то получила бы значение nice +10. Если вы откорректируете это значение командой
$ <b>renice 10 1362</b>
1362: old priority 0, new priority 10
программа oclock будет выполняться реже. Увидеть измененное значение nice можно снова с помощью команды ps:
$ ps -l
F S UID PID PPID С PRI NI ADDR SZ WCHAN TTY TIME CMD
000 S 500 1259 1254 0 75 0 - 710 wait4 pts/2 00:00:00 bash
000 S 500 1262 1251 0 75 0 - 714 wait4 pts/1 00:00:00 bash
000 S 500 1313 1262 0 75 0 - 2762 schedu pts/1 00:00:00 emacs
000 S 500 1362 1262 0 90 10 - 789 schedu pts/1 00:00:00 oclock
000 R 500 1365 1262 0 81 0 - 782 - pts/1 00:00:00 ps
Столбец состояния теперь также содержит N, указывая на то, что значение nice было изменено по сравнению с принятым по умолчанию:
$ <b>ps х</b>
PID TTY STAT TIME COMMAND
1362 pts/1 SN 0:00 oclock