RFC (Request for Comments, Запрос на комментарии) - серия документов, публикуемая сообществом исследователей и разработчиков, руководствующихся практическими интересами, в которой описывается набор протоколов и обобщается опыт функционирования Интернет.
В этой статье, состоящей из трех частей, я хочу рассказать вам о процессах. В этой части мы узнаем, что такое процесс и как посмотреть информацию о ваших процессах. В следующей части мы посмотрим, как сделать что-нибудь полезное с этой информацией.
Как любая другая UNIX-система, FreeBSD является многозадачной, многопользовательской операционной системой. Это значит, что несколько пользователей могут выполнять несколько программ одновременно. Ядро системы отвечает за то, что каждая из этих программ гарантированно получит процессорное время, и что каждый пользователь увидит верные результаты, выданные этими программами.
Когда вы запускаете программу, она загружается в оперативную память, и после этого ее называют процессом, так как ее инструкции требуют обработки (процесса) процессором. Для того, что бы ядро могло разобраться какой пользователь запускал какие программы, каждому процессу присваивается идентификатор ID (иначе PID – process ID). Обычно PID ассоциируется с, и имеет такие же права, как пользователь, который запустил программу и как группа к которой принадлежит этот пользователь.
Не все программы запускаются пользователями, некоторые из них запускаются вашей FreeBSD во время старта системы и называются демонами. В свою очередь некоторые программы, или запускаются другими программами, или являются экземплярами самих себя. Первоначальную программу называют родительским процессом, а создаваемые им процессы – детьми.
Когда вы установили FreeBSD, для вас была создана файловая система процессов (procfs). Если вы напечатаете:
$ more /etc/fstab
среди прочего, вы должны будете увидеть следующие строки:
Когда вы просматриваете информацию о свободном пространстве на ваших дисках, вы можете заметить, что эта файловая система всегда заполнена на 100%:
$ df
Filesystem Size Used Avail Capacity Mounted on
procfs 4.0K 4.0K 0B 100% /proc
Это нормально, так как файловая система процессов не предназначена для хранения файлов, создаваемых пользователями. Эта файловая система используется командами ps и w для получения информации о запущенных процессах. Обратите внимание, что файловая система процессов смонтирована в каталоге /proc. Давайте поглядим на содержимое /proc используя команду ls с ключом C для сортировки вывода по столбцам и с ключом F для печати каталогов со слэшем (/):
Заметьте, что каждая запись, кроме одной, это каталог с именем состоящим из цифр. Эти числа соответствуют идентификаторам PID запущенных процессов. Последняя запись, curproc, это символьная ссылка, поскольку она заканчивается знаком @. Для того что бы понять на какой файл указывает эта ссылка, напечатайте:
$ file curproc
curproc: symbolic link to 2072
Это означает, что ссылка curproc указывает на какой-то процесс. Если вы напишете:
$ man 5 procfs
вы сможете прочитать, что на самом деле curproc указывает на текущий процесс, который обращается к системе /proc. Таким образом моя команда ls имела идентификатор PID равный 2072.
Теперь давайте посмотрим какая информация хранится о каждом запущенном процессе, путем просмотра содержимого одного из этих каталогов:
$ ls -CF 197
./ ctl file@ mem regs
../ dbregs fpregs note rlimit
cmdline etype map notepg status
Все записи – это обычные файлы, исключая символьную ссылку с именем file. Однако мы совершенно не представляем себе какие данные содержат эти файлы. Попробуем узнать:
$ file *
cmdline: empty
ctl: empty
dbregs: MS Windows COFF Unknown CPU
etype: empty
file: symbolic link to /usr/sbin/inetd
fpregs: data
map: empty
mem: empty
note: empty
notepg: empty
regs: data
rlimit: empty
status: empty
Пожалуй это не выглядит так, как если бы мы могли посмотреть эти файлы сами, поскольку они не содержат читабельного текста. Это создает ощущение, что эта файловая система хранит данные полезные для ядра системы. Однако, не смотря на то, что вы не сможете посмотреть данные напрямую, вы можете воспользоваться утилитами w и ps, которые знают как интерпретировать и показать информацию содержащуюся в этих файлах.
Начнем с команды w:
$ whatis w
w(1) - display who is logged in and what they are doing
w(1) - показывает кто сейчас находится в системе и что они делают
$ w
10:43AM up 17:50, 4 users, load averages: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE WHAT
genisis v0 - 9:46AM - w
genisis v1 - Sat04PM 2:02 -csh (csh)
genisis v2 - Sat08PM - -csh (csh)
genisis v3 - Sat05PM 2:02 -csh (csh)
Первая строка показывает текущее системное время, затем время непрерывной работы вашей системы с последней перезагрузки, количество пользователей, в данный момент находящихся в системе и среднее количество заданий в очереди на обработку за 1, 5, 15 последних минут.
Оставшиеся строки показывают регистрационные имена пользователей, названия терминалов с которых зашли эти пользователи, время захода пользователей в систему, время прошедшее после последнего нажатия пользователем какой-нибудь клавиши и имя и параметры текущего пользовательского процесса.
Если мы воспользуемся командой w с ключом d, то мы получим немного отличающийся вывод, поскольку w будет показывать все процессы которые пользователь выполняет с его терминала:
$w -d
10:55AM up 18:02, 4 users, load averages: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE WHAT
2100 -csh (csh)
2104 su (csh)
2235 w -d
genisis v0 - 9:46AM - w -d
313 -csh (csh)
genisis v1 - Sat04PM 2:14 -csh (csh)
314 -csh (csh)
genisis v2 - Sat08PM - -csh (csh)
315 -csh (csh)
genisis v3 - Sat05PM 2:14 -csh (csh)
Числа над названием терминала это идентификаторы PID процессов. Если вы прочитаете страницу руководства по команде w, то вы узнаете, что это отличная утилита для того что бы быстро посмотреть кто сейчас, и с каких терминалов, находится в системе и что они делают. Однако она не предназначена для детального выяснения информации о процессах, так как это работа утилиты ps. Если вы просто напишете:
$ ps
вы получите базовую информацию о процессах, которые вы запустили, примерно вот так:
PID TT STAT TIME COMMAND
2100 v0 Ss 0:00.13 -csh (csh)
2286 v0 R+ 0:00.00 ps
313 v1 Is+ 0:00.13 -csh (csh)
314 v2 Is+ 0:00.21 -csh (csh)
315 v3 Is 0:00.12 -csh (csh)
Если читать выдачу слева направо, то команда ps показывает PID, название и тип терминала, состояние, затраченное процессорное время (суммируя системное и пользовательское время) и ассоциированную команду, для процессов, которые запущены пользователем выполняющим команду ps.
Состояние - это новый термин, который предоставляет различную информацию о запущенном процессе. При чтении столбца состояния (STAT), первая буква показывает текущий режим выполнения процесса. Возможные значения этой буквы:
D – процесс находится в ожидании дисковой (или короче, непрерываемой) операции I – процесс в ожидающем режиме (процесс «спит» более 20 секунд) J – процесс в «тюрьме» (см. man 2 jail – прим. переводчика) R – процесс выполняется S – процесс «спит» менее 20 секунд T – процесс остановлен Z – мертвый (зомби) процесс
Итак у меня выполняется один процесс (сама команда ps), одна оболочка csh, которая ничего не делала последние 20 секунд и три оболочки, которые ничего не делают более 20 секунд. Символ + показывает что три моих процесса выполняются на переднем плане (foreground-процессы), s говорит о том, что четыре моих процесса являются начальными в сеансе. Не беспокойтесь, если некоторая информация о состоянии процесса не представляется вам важной, действительно, если вы не программист, то некоторая ее часть не будет вам нужна.
Имейте в виду, что команда ps без ключей, по умолчанию покажет вам только ваши процессы, для того что бы посмотреть процессы всех пользователей запущенные на вашем компьютере, используйте ключ a:
$ ps -a
PID TT STAT TIME COMMAND
2100 v0 Ss 0:00.18 -csh (csh)
2403 v0 R+ 0:00.00 ps -a
313 v1 Is+ 0:00.13 -csh (csh)
314 v2 Is+ 0:00.25 -csh (csh)
315 v3 Is+ 0:00.12 -csh (csh)
316 v4 Is+ 0:00.01 /usr/libexec/getty Pc ttyv4
317 v5 Is+ 0:00.01 /usr/libexec/getty Pc ttyv5
318 v6 Is+ 0:00.01 /usr/libexec/getty Pc ttyv6
319 v7 Is+ 0:00.01 /usr/libexec/getty Pc ttyv7
Вы можете решить, что более удобно видеть какие пользователи запустили какую команду, для этого воспользуйтесь ключом u:
Однако, пока мы не видим все процессы, которые запущены на этой машине. Для того что бы посмотреть какие запущены демоны воспользуемся ключом x. Вывод скорее всего будет длинным, поэтому перенаправим его команде more:
Вот это да! Неудивительно, что ядру приходится давать каждому процессу свои идентификатор для того что бы отслеживать все что твориться в вашей FreeBSD. Если при многостраничном выводе вам трудно запомнить какой столбец что означает, воспользуйтесь ключом «h», для того что бы заставить команду ps переписывать заголовки столбцов при многостраничном выводе.
Вы могли заметить, что состав столбцов вывода расширился, когда мы добавили ключ u, из вновь появившихся, наиболее интересны столбцы %CPU и %MEM. Время от времени вам может понадобиться отсортировать вывод команды ps в порядке уменьшения использования памяти или процессора, а не по идентификаторам. Для сортировки по размеру используемой памяти применяется ключ m, а по используемому процессорному времени – ключ r.
Ключи команды ps, которые я описал, на практике используются наиболее часто. Вы можете почитать руководство по команде ps для того, что бы узнать о остальных ключах, и после этого выбрать комбинацию ключей, которая бы наиболее соответствовала вашим потребностям.
Когда вы используете команду ps, вы можете увидеть процессы, о которых никогда раньше не слышали. В этом случае, для того что бы найти страницу руководства, способную пролить свет на тайну, используйте команду whatis. Например, являясь очень любопытным субъектом, я попробовал следующее:
$ whatis init syncer adjkerntz inetd portmap rpc.statd
init(8) - process control initialization
(процесс контролирующий инициализацию)
syncer(4) - filesystem synchronizer kernel process
(процесс ядра синхронизирующий файловую систему)
adjkerntz(8) - adjust local time CMOS clock to reflect time zone
changes and keep current timezone offset for the kernel
(настраивает часы компьютера согласно изменениям часового
пояса, а так же хранит текущее смещение относительно
часового пояса для ядра)
inetd.conf(5), inetd(5) - internet super-server
(интернет-суперсервер)
portmap(8) - RPC program, version to DARPA port mapper
(программа RPC, версия DARPA распределителя портов)
rpc.statd(8) - host status monitoring daemon
(демон мониторинга системы)
Это заставило меня на некоторое время заняться чтением. Это должно дать и вам много поводов для занятий перед следующей частью этой статьи, в которой мы посмотрим, что мы можем сделать с этими новыми знаниями.