Рейтинговые книги
Читем онлайн Основы программирования в Linux - Нейл Мэтью

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 122 123 124 125 126 127 128 129 130 ... 200

10438 ?     Ss   0:00 /usr/bin/ssh-agent /bin/bash /etc/X11/xinit/xinitrc

10478 ?     S    0:00 start_kdeinit --new-startup +kcminit_startup

10479 ?     Ss   0:00 kdeinit Running...

10500 ?     S    0:53 kdesktop [kdeinit]

10502 ?     S    1:54 kicker [kdeinit]

10524 ?     Sl   0:47 beagled /usr/lib/beagle/BeagleDaemon.exe --bg

10530 ?     S    0:02 opensuseupdater

10539 ?     S    0:02 kpowersave [kdeinit]

10541 ?     S    0:03 klipper [kdeinit]

10555 ?     S    0:01 kio_uiserver [kdeinit]

10688 ?     S    0:53 konsole [kdeinit]

10689 pts/1 Ss+  0:07 /bin/bash

10784 ?     S    0:00 /opt/kde3/bin/kdesud

11052 ?     S    0:01 [pdflush]

19996 ?     SN1  0:20 beagled-helper /usr/lib/beagle/IndexHelper.exe

20254 ?     S    0:00 qmgr -1 -t fifo -u

21192 ?     Ss   0:00 /usr/sbin/ntpd -p /var/run/ntp/ntpd.pid -u ntp -i /v

21198 ?     S    0:00 pickup -1 -t fifo -u

21475 pts/2 R+   0:00 ps ax

Здесь вы видите на самом деле очень важный процесс

1     ?     Ss   0:03 init [5]

В основном каждый процесс запускается другим процессом, называемым родительским или порождающим процессом. Подобным образом запущенный процесс называют дочерним или порожденным. Когда стартует ОС Linux, она выполняет единственную программу, первого предка и процесс с номером 1, init. Это, если хотите, диспетчер процессов операционной системы и прародитель всех процессов. Другие системные процессы, с которыми вы вскоре встретитесь, запускаются процессом init или другим процессом, запущенным процессом init.

Один из таких примеров — процедура регистрации. Процесс 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).

$ 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 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 по умолчанию. Если бы она была запущена командой

$ nice oclock &

то получила бы значение nice +10. Если вы откорректируете это значение командой

$ renice 10 1362

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 было изменено по сравнению с принятым по умолчанию:

ps х

PID  TTY   STAT TIME COMMAND

1362 pts/1 SN   0:00 oclock

Поле PPID в выводе команды ps содержит ID родительского процесса (PID), либо процесса, запустившего данный процесс, либо, если этот процесс уже не выполняется, процесса init (PID, равный 1).

Планировщик процессов ОС Linux решает, какому процессу разрешить выполнение, на основе приоритета. Конкретные реализации конечно отличаются, но высокоприоритетные процессы выполняются чаще. В некоторых случаях низкоприоритетные процессы не выполняются совсем, если высокоприоритетные процессы готовы к выполнению.

Запуск новых процессов

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

#include <stdlib.h>

int system(const char *string);

Функция system выполняет команду, переданную ей как строку, и ждет ее завершения. Команда выполняется, как если бы командной оболочке была передана следующая команда:

$ sh -с string

Функция system возвращает код 127, если командная оболочка не может быть запущена для выполнения команды, и -1 в случае другой ошибки. Иначе system вернет код завершения команды.

Выполните упражнение 11.1.

Упражнение 11.1. Функция system

Вы можете использовать system для написания программы, выполняющей команду ps. Хотя нельзя сказать, что она необычайно полезна, вы увидите, как применять этот метод в последующих примерах. (Для простоты примера мы не проверяем, работает ли на самом деле системный вызов.)

1 ... 122 123 124 125 126 127 128 129 130 ... 200
На этой странице вы можете бесплатно читать книгу Основы программирования в Linux - Нейл Мэтью бесплатно.
Похожие на Основы программирования в Linux - Нейл Мэтью книги

Оставить комментарий