Что такое ppid linux

Что такое ppid linux

Эта глава открывает большую и очень важную для Linux-программиста тему многозадачности. Описать все сразу не получится, поэтому мы будем неоднократно возвращаться к многозадачности в последующих главах книги. Пристегните ремни покрепче!

Наберите в своей оболочке следующую команду:

На экран будут выведен список всех работающих в системе процессов. Если хотите посчитать количество процессов, наберите что-нибудь, набодобие этого:

Первое число — это количество работающих в системе процессов. Пользователи KDE могут воспользоваться программой kpm, а пользователи Gnome — программой gnome-system-monitor для получения информации о процессах. На то он и Linux, чтобы позволять пользователю делать одно и то же разными способами.

Возникает вопрос: «Что такое процесс?». Процессы в Linux, как и файлы, являются аксиоматическими понятиями. Иногда процесс отождествляют с запущенной программой, однако это не всегда так. Будем считать, что процесс — это рабочая единица системы, которая выполняет что-то. Многозадачность — это возможность одновременного сосуществования нескольких процессов в одной системе.

Linux — многозадачная операционная система. Это означает что процессы в ней работают одновременно. Естественно, это условная формулировка. Ядро Linux постоянно переключает процессы, то есть время от времени дает каждому из них сколько-нибудь процессорного времени. Переключение происходит довольно быстро, поэтому нам кажется, что процессы работают одновременно.

Одни процессы могут порождать другие процессы, образовывая древовидную структуру. Порождающие процессы называются родителями или родительскими процессами, а порожденные — потомками или дочерними процессами. На вершине этого «дерева» находится процесс init, который порождается автоматически ядром в процесссе загрузки системы.

К каждому процессу в системе привязана пара целых неотрицательных чисел: идентификатор процесса PID (Process IDentifier) и идентификатор родительского процесса PPID (Parent Process IDentifier). Для каждого процесса PID является уникальным (в конкретный момент времени), а PPID равен идентификатору процесса-родителя. Если ввести в оболочку команду ps -ef, то на экран будет выведен список процессов со значениями их PID и PPID (вторая и третья колонки соотв.). Вот, например, что творится у меня в системе:

Надо отметить, что процесс init всегда имеет идентификатор 1 и PPID равный 0. Хотя в реальности процесса с идентификатором 0 не существует. Дерево процессов можно также пресставить в наглядном виде при помощи опции —forest программы ps:

Если вызвать программу ps без аргументов, то будет выведен список процессов, принадлежащих текущей группе, то есть работающих под текущим терминалом. О том, что такое терминалы и группы процессов, будет рассказано в последующих главах.

6.2. Использование getpid() и getppid()

Процесс может узнать свой идентификатор (PID), а также родительский идентификатор (PPID) при помощи системных вызовов getpid() и getppid().

Системные вызовы getpid() и getppid() имеют следующие прототипы:

Для использования getpid() и getppid() в программу должны быть включены директивой #include заголовочные файлы unistd.h и sys/types.h (для типа pid_t). Вызов getpid() возвращает идентификатор текущего процесса (PID), а getppid() возвращает идентификатор родителя (PPID). pid_t — это целый тип, размерность которого зависит от конкретной системы. Значениями этого типа можно оперировать как обычными целыми числами типа int.

Рассмотрим теперь простую программу, которая выводит на экран PID и PPID, а затем «замирает» до тех пор, пока пользователь не нажмет .

Проверим теперь, как работает эта программа. Для этого откомпилируем и запустим ее:

Теперь, не нажимая , откроем другое терминальное окно и проверим, правильность работы системных вызовов getpid() и getppid():

6.3. Порождение процесса

Как уже говорилось ранее, процесс в Linux — это нечто, выполняющее программный код. Этот код называют образом процесса (process image). Рассмотрим простой пример, когда вы находитесь в оболочке bash и выполняете команду ls. В этом случае происходит следующее. Образ программы-оболочки bash выполняется в процессе #1. Затем вы вводите команду ls, и оболочка определяет, что нужно запустить внешнюю программу (/bin/ls). Тогда процесс #1 создает свою почти точную копию, процесс #2, который выполняет тот же самый программный код. После этого процесс #2 заменяет свой текущий образ (оболочку) другим образом (программой /bin/ls). В итоге получаем отдельный процесс, выполняющий отдельную программу.

«К чему такая путаница?» — спросите вы. Зачем сначала «клонировать» процесс, а затем заменять в нем образ? Не проще ли все делать одной-единственной операцией? Ответы на подобные вопросы дать тяжело, но, как правило, с опытом прихоидит понимание того, что подобная схема является одной из граней красоты Unix-систем.

Попробуем все-таки разобраться, почему в Unix-системах порождение процесса отделено от запуска программы. Для этого выясним, что же происходит с данными при «клонировании» процесса. Итак, каждый процесс хранит в своей памяти различные данные (переменные, файловые дескрипторы и проч.). При порождении нового процесса, потомок получает точную копию данных родителя. Но как только новый процесс создан, родитель и потомок уже распоряжаются своими копиями по своему усмотрению. Это позволяет распараллелить программу, заставив ее выполнять какой-нибудь трудоемкий алгоритм в отдельном процессе.

Может быть кто-то из вас слышал про то, что в Linux есть потоки, которые позволяют в одной программе реализовывать параллельное выполнение нескольких функций. Опять же возникает вопрос: «Если есть потоки, зачем вся эта головомойка с клонированиями и заменой образов?». А дело в том, что потоки работают с общими данными и выполняются в одной программе. Если в потоке произошло что-то страшное, то это, как правило, отражается на всей программе в целом. Хотя технически потоки реализованы в Linux на базе процессов, но процесс все же является более независимой единицей. Крах дочернего процесса никак не отражается на работе родителя, если сам родитель этого не пожелает.

Читайте также:  Как завести домен windows 10

По правде сказать, программисты редко прибегают к методике распараллеливания одной программы при помощи процессов. Но суть в том, что в Unix-системах программист обладает полной свободой выбора стратегии многозадачности. И это здорово!

Разберемся теперь с тем, как на практике происходит «клонирование» процессов. Для этого используется простой системный вызов fork(), прототип которого находится в файле unistd.h:

Если fork() завершается с ошибкой, то возвращается -1. Это редкий случай, связанный с нехваткой памяти или превышением лимита на количество процессов. Но если разделение произошло, то программе нужно позаботиться об идентификации своего «Я», то есть определении того, где родитель, а где потомок. Это делается очень просто: в родительский процесс fork() возвращает идентификатор потомка, а потомок получает 0. Следующий пример демонстрирует то, как это происходит.

Проверяем, что получилось:

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

6.4. Замена образа процесса

Итак, теперь мы умеем порождать процессы. Научимся теперь заменять образ текущего процесса другой программой. Для этих целей используется системный вызов execve(), который объявлен в заголовочном файле unistd.h вот так:

Все очень просто: системный вызов execve() заменяет текущий образ процесса программой из файла с именем path, набором аргументов argv и окружением envp. Здесь следует только учитывать, что path — это не просто имя программы, а путь к ней. Иными словами, чтобы запустить ls, нужно в первом аргументе указать «/bin/ls».

Массивы строк argv и envp обязательно должны заканчиваться элементом NULL. Кроме того, следует помнить, что первый элемент массива argv (argv[0]) — это имя программы или что-либо иное. Непосредственные аргументы программы отсчитываются от элемента с номером 1.

В случае успешного завершения execve() ничего не возвращает, поскольку новая программа получает полное и безвозвратное управление текущим процессом. Если произошла ошибка, то по традиции возвращается -1.

Рассмотрим теперь пример программы, которая заменяет свой образ другой программой.

Итак, данная программа выводит свой PID и передает безвозвратное управление программе cat без аргументов и без окружения. Проверяем:

Программа вывела идентификатор процесса и замерла в смиренном ожидании. Откроем теперь другое терминальное окно и проверим, что же творится с нашим процессом:

Итак, мы убедились, что теперь процесс 30150 выполняет программа cat. Теперь можно вернуться в исходное окно и нажатием Ctrl+D завершить работу cat.

И, наконец, следующий пример демонстрирует запуск программы в отдельном процессе.

Обратите внимание, что поскольку execve() не может возвращать ничего кроме -1, то для обработки возможной ошибки вовсе не обязательно создавать ветвление. Иными словами, если вызов execve() возвратил что-то, то это однозначно ошибка.

Источник

Как найти родительский процесс в Linux

Во время выполнения программы ядро ​​создает процесс, который помогает сохранять детали выполнения программы в системной памяти. Когда программа выполняется, она становится процессом для системы. Итак, мы можем сказать, что процесс — это программа, пока он не выполняется.

Процесс, созданный ядром, известен как » родительский процесс «, а все процессы, производные от родительского процесса, называются » дочерними процессами «. Один процесс может состоять из нескольких дочерних процессов, имеющих уникальный PID, но с одним и тем же PPID.

У новичка может возникнуть вопрос: в чем разница между PID и PPID?

Мы уже обсуждали PID в большинстве наших статей, если вы новичок, не беспокойтесь!

В системах Linux одновременно выполняется несколько процессов. Иногда процесс может иметь один поток (блок выполнения внутри процесса) или несколько потоков. Процессы имеют разные состояния; они могут находиться в состоянии ожидания, готовности или работы. Все дело в том, как пользователь или ядро ​​расставляют приоритеты. Итак, эти процессы идентифицируются уникальными номерами, которые мы называем идентификатором процесса (PID). Уникальные номера для родительских процессов называются PPID, и каждый родительский процесс может иметь несколько дочерних процессов с их уникальными идентификаторами. PID дочерних процессов отличаются, поскольку они представляют собой отдельные исполнительные единицы, но имеют один и тот же идентификатор родительского процесса ( PPID ).

Нам нужен PPID, когда дочерний процесс создает проблемы и не работает должным образом. В этом случае это может повлиять на работу других процессов, а также на систему. Здесь, чтобы остановить непрерывно работающий процесс, необходимо убить его родительский процесс.

Давайте проверим, как мы можем найти PPID:

Как найти идентификатор родительского процесса (PPID) в Linux

У нас есть несколько подходов к поиску PPID запущенного процесса в системах Linux:

  1. Использование команды «pstree»
  2. Использование команды «ps»

Как найти PPID с помощью команды pstree в Linux

Команда » pstree » — хороший подход для определения идентификатора родительского процесса (PPID), поскольку она показывает отношения родитель-потомок в древовидной иерархии.

Введите в терминале просто команду » pstree » с параметром » -p «, чтобы проверить, как он отображает все запущенные родительские процессы вместе с их дочерними процессами и соответствующими PID.

Он показывает родительский идентификатор вместе с идентификаторами дочерних процессов.

Давайте рассмотрим пример „Mozilla Firefox“, чтобы получить его PPID вместе с полной иерархией процессов. Выполните в терминале следующую команду:

( grep — это инструмент командной строки, который помогает искать определенную строку)

В упомянутых результатах мы видим, что 3528 — это PPID процесса » Firefox «, а все остальные — дочерние процессы.

Читайте также:  Как установить драйвера видеокарты линукс

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

Как найти PPID с помощью команды ps

Утилита команды » ps » — это еще один способ обрабатывать информацию из файловой системы » / proc » и отслеживать ее.

С помощью этой команды пользователь также может найти PPID и PID запущенного процесса.

Выполните следующую команду » ps » вместе с параметром » ef «, чтобы отобразить подробную информацию о процессах, включая PPID :

Если вы хотите отобразить PPID определенного процесса с подробностями, выполните указанную команду » ps » с помощью » grep «:

( опция » -f » используется для перечисления деталей процесса)

А чтобы получить только PPID » Firefox «, используйте следующий синтаксис:

Итак, найдите PPID » firefox » с помощью команды:

Заключение

При каждом выполнении программы ядро ​​создает процесс, который загружает детали выполнения в память. Этот созданный процесс известен как родительский процесс, имеющий один или несколько потоков. Каждому процессу ядро автоматически присваивает уникальный PPID и PID.

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

Идентификаторы PPID запущенных процессов можно определить несколькими способами. Самый простой подход — использовать команду » ps » и » pstree «.

Выше мы видели, как с помощью этих двух командных инструментов можно узнать PPID конкретного процесса.

Источник

Администрирование систем Linux. Вводная информация об управлении процессами

Часть I. Управление процессами

Глава 1. Вводная информация об управлении процессами

1.1. Терминология

Процесс является скомпилированным исходным кодом, исполняющимся в текущее время в системе.

1.1.2. Идентификатор процесса PID

Каждый из процессов имеет идентификатор или PID (сокращение process id ).

1.1.3. Идентификатор родительского процесса PPID

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

1.1.4. Процесс init

Процесс init всегда имеет идентификатор PID, равный 1. Процесс init запускается средствами ядра операционной системы и, следовательно, не имеет родительского процесса. Процесс init исполняет обязанности приемного родителя для осиротевших процессов.

1.1.5. Уничтожение процесса

Завершение работы процесса чаще всего достигается благодаря его уничтожению, поэтому в том случае, если вы хотите остановить исполнение процесса, вы должны уничтожить его.

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

Уничтоженный процесс, информация о котором сохраняется в рамках системы, называется зомби-процессом . Вы не можете уничтожить зомби-процессы, так как они уже были уничтожены ранее и не исполняются.

1.2. Базовые приемы управления процессами

1.2.1. Переменные командной оболочки $$ и $PPID

Некоторые переменные командной оболочки содержат информацию о процессах. Переменная $$ будет хранить идентификатор используемого вами в данный момент процесса командной оболочки, а переменная $PPID — идентификатор соответствующего родительского процесса . На самом деле $$ является параметром командной оболочки, а не переменной, так как вы не можете установить значение этого параметра.

Ниже приведен пример использования утилиты echo для вывода значений $$ и $PPID .

1.2.2. Утилита pidof

Вы можете получить все идентификаторы процессов на основе известного имени процесса, воспользовавшись утилитой pidof .

1.2.3. Родительские и дочерние процессы

Иерархия процессов системы строится на отношении родительский процесс — дочерний процесс . Каждый процесс в системе имеет родительский процесс.

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

Ввод команды exit приведет к завершению исполнения текущего процесса и возврату в командную оболочку с оригинальными значениями $$ и $PPID .

1.2.4. Системные вызовы fork и exec

Процесс инициирует исполнение другого процесса в два этапа. На первом этапе он создает свою точную копию с помощью системного вызова fork . После этого в рамках копии процесса выполняется системный вызов exec , предназначенный для замены скопированных данных родительского процесса на данные дочернего процесса.

1.2.5. Команда exec

Благодаря команде exec вы можете инициировать исполнение нового процесса, минуя этап создания точной копии текущего процесса. В следующем примере осуществляется запуск командной оболочки Korn Shell (ksh) с последующей заменой на командную оболочку bash с помощью команды exec . Идентификатор процесса командной оболочки bash остается равным идентификатору процесса командной оболочки Korn Shell . При этом после завершения работы с дочерней командной оболочкой bash происходит перемещение в родительскую командную оболочку bash , а не в командную оболочку Korn shell (процесса которой более не существует).

Одним из наиболее часто используемых инструментов для ознакомления со списком процессов в Linux является утилита ps . В следующем примере показаны отношения между тремя родительскими и дочерними процессами bash.

В Linux обычно используется команда ps fax . В Solaris же чаще всего используется команда ps -ef (которая также работает в Linux). Ниже приведен фрагмент вывода команды ps fax .

1.2.7. Утилита pgrep

По аналогии с командой ps -C , вы также можете использовать утилиту pgrep для поиска информации о процессе по его имени.

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

1.2.8. Утилита top

Другим популярным инструментом для получения информации о процессах в Linux является утилита top . Утилита top может упорядочивать список процессов в соответствии с создаваемой ими нагрузкой на центральный процессор , а также с другими параметрами. Кроме того, вы можете уничтожать процессы средствами утилиты top. Нажмите клавишу h в процессе работы с утилитой top для ознакомления со справочной информацией.

Читайте также:  Драйвер для usb wifi для linux

В случае неполадок утилита top является первым инструментом, который следует применять для диагностики системы, так как помимо информации о процессах она может предоставить информацию об использовании оперативной памяти и раздела подкачки вашей системы.

1.3. Отправка сигналов процессам

1.3.1. Утилита kill

Утилита kill позволяет уничтожить процесс (или остановить его исполнение). В примере ниже показана стандартная методика использования утилиты kill для остановки исполнения процесса с идентификатором 1942.

На самом деле в процессе использования утилиты kill осуществляется передача сигнала процессу.

1.3.2. Список сигналов

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

1.3.3. Команда kill -1 (SIGHUP)

Первый сигнал SIGHUP (или HUP, или 1) часто используется в Linux для сообщения процессу о необходимости повторного чтения файла конфигурации. Таким образом, команда kill -1 1 приведет к принудительному повторному чтению файла конфигурации процессом init (процесс init всегда имеет идентификатор 1 ).

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

1.3.4. Команда kill -15 (SIGTERM)

Сигнал SIGTERM также часто называется стандартным сигналом уничтожения процесса . При использовании утилиты kill без указания сигнала предполагается, что исполняется команда kill -s 15 .

Команды в примере ниже являются идентичными.

1.3.5. Команда kill -9 (SIGKILL)

Сигнал SIGKILL отличается от большинства сигналов тем, что он отправляется не процессу, а непосредственно ядру Linux . Команда kill -9 также называется надежной командной уничтожения процесса . Ядро операционной системы гарантированно завершит исполнение указанного процесса. Как разработчик вы не можете ни коим образом перехватить сигнал, генерируемый в результате исполнения команды kill -9 .

1.3.6. Сигналы SIGSTOP и SIGCONT

Исполнение процесса может быть приостановлено в случае приема сигнала SIGSTOP . Данный сигнал может быть отправлен процессу с помощью команды kill -19 в Linux, причем в других системах Unix номер сигнала может отличаться.

Приостановленный процесс не использует циклов центрального процессора , но находится в памяти и может быть реанимирован с помощью сигнала SIGCONT (отправляемого с помощью команды kill -18 в Linux).

Оба этих сигнала будут использоваться в главе, посвященной описанию процессов, исполняющихся в фоновом режиме .

1.3.7. Утилита pkill

Вы можете использовать утилиту pkill для завершения работы процесса на основе его имени.

1.3.8. Утилита killall

Утилита killall позволяет отправлять сигнал 15 всем процессам с определенным именем.

1.3.9. Утилита killall5

Аналог описанной выше утилиты из мира SysV, утилита killall5 , может использоваться в процессе завершения работы системы. В данном примере показано, как утилита killall5 используется в дистрибутиве Red Hat Enterprise Linux 5.3 для уничтожения процессов при завершении работы системы.

1.3.10. Утилита top

При работе с утилитой top кнопка k позволит вам выбрать сигнал и идентификатор процесса , которому этот сигнал будет отправлен. В примере ниже приведена строка, выводимая под строками с общей информацией о состоянии системы после нажатия клавиши k .

1.4. Практическое задание: вводная информация об управлении процессами

1. Используйте утилиту ps для поиска информации о процессе с именем init .

2. Каков идентификатор процесса с именем init ?

3. Используйте команду who i am для установления имени пользователя, под которым вы работаете с терминалом.

4. Располагая полученной ранее информацией о вашем имени пользователя, примените утилиту ps для поиска всех процессов, запущенных с помощью вашего терминала.

5. Каков идентификатор процесса вашей командной оболочки?

6. Каков идентификатор родительского процесса вашей командной оболочки?

7. Запустите в фоновом режиме два экземпляра процесса с помощью команд sleep 3342 .

8. Определите идентификаторы всех процессов с именем sleep .

9. Выведите информацию только о двух запущенных ранее процессах sleep с помощью утилиты top. После этого завершите работу утилиты top .

10. Используйте стандартный сигнал уничтожения процесса для уничтожения одного из двух созданных ранее процессов с именами sleep .

11. Используйте одну команду для уничтожения всех процессов с именем sleep .

1.5. Корректная процедура выполнения практического задания: вводная информация об управлении процессами

1. Используйте утилиту ps для поиска информации о процессе с именем init .

2. Каков идентификатор процесса с именем init ?

3. Используйте команду who i am для установления имени пользователя, под которым вы работаете с терминалом.

4. Располагая полученной ранее информацией о вашем имени пользователя, примените утилиту ps для поиска всех процессов, запущенных с помощью вашего терминала.

или может быть использована аналогичная команда

5. Каков идентификатор процесса вашей командной оболочки?

2973 в примере выше, в вашем случае наверняка будет использоваться отличный идентификатор процесса

Команда echo $$ позволит получить аналогичное найденному значение

6. Каков идентификатор родительского процесса вашей командной оболочки?

2972 в примере выше, в вашем случае наверняка будет использоваться отличный идентификатор родительского процесса

В данном примере родительским процессом является процесс su — , в то время, как при работе в окружении рабочего стола gnome родительским процессом может оказаться процесс gnome-terminal

7. Запустите в фоновом режиме с помощью команд sleep 3342 два экземпляра процесса.

8. Определите идентификаторы всех процессов с именем sleep .

9. Выведите информацию только о двух запущенных ранее процессах sleep с помощью утилиты top . После этого завершите работу утилиты top.

top -p pidx,pidy (замените pidx, pidy на действительные значения идентификаторов процессов)

10. Используйте стандартный сигнал уничтожения процесса для уничтожения одного из двух созданных ранее процессов с именами sleep .

11. Используйте одну команду для уничтожения всех процессов с именем sleep .

Источник

Оцените статью