Управление процессами в Linux. Завершить процесс в Linux — команды ps, kill и killall

Инструкция

Internet Protocol (IP) определяет доставку данных от одного узла сети до другого. При этом он не гарантирует точность доставки: пакеты при передаче могут теряться или поступать не в том порядке, в котором были отправлены. За точность отвечает протокол транс ного уровня Transmission Control Protocol – TCP. TCP устанавливает соединение, контролирует отправку и получение пакетов, дублирует свои действия в том случае, если ответ на запрос не получен или пакеты потерялись. Важно понимать, что TCP устанавливает обмен пакетами не просто между узлами, а между программными приложениями. Сетевой порт – это условное , число от 1 до 65535, которое указывает, какому приложению назначен пакет.

Узнать, какими процессами используются порты на компьютере, можно при помощи стандартных средств Windows. В меню «Пуск» нажмите «выполнить» и в командную строку введите cmd. Подтвердите ОК. В окне консоли наберите команду netstat -a -n -o.

В столбце PID указан номер процесса, в столбце « » - IP-адрес вашего компьютера и, через двоеточие, номер порта, который занят соответствующим процессом. «Внешний адрес» – это IP и номер порта удаленного узла, с которым работает какое-то приложение.

В окне консоли наберите команду tasklist. Она выдаст список всех приложений с кодом PID, которые выполняются на компьютере. Таким образом вы узнаете, какой именно процесс занимает любой порт на вашем компьютере.

Можете получить эти сведения иначе: запустите "Диспетчер задач" из командной строки, набрав taskmgr, или комбинацией клавиш Ctrl+Alt+Delete. В столбце PID найдите номер интересующего вас процесса, в столбце «Имя образа» – название соответствующего приложения или службы. Если PID не отображается в окне Диспетчера, зайдите в пункт «Вид» главного меню и выбирайте опцию «Выбрать столбцы». Поставьте флаг рядом с пунктом «Идентиф.процесса (PID)».

Когда на компьютере запускается какой-либо процесс, он получает свой pid, то есть идентификатор процесса . Иногда возникает необходимость узнать этот самый идентификатор. Возможно, вам по каким-либо причинам нужно отключить запущенный процесс, например, если он мешает удалению программы. Существует несколько способов, позволяющих узнать pid. Самый простой из них: сделать это с помощью диспетчера задач и командной строки.

Вам понадобится

  • - компьютер с ОС Windows (XP, Windows 7).

Инструкция

Нажмите на клавиатуре сочетание клавиш ctrl+alt+del. Если вашей операционной системой является Windows ХР, то диспетчер задач появится сразу, если же Windows 7 - появится окно, в котором его можно выбрать.

В выберите вкладку «Процессы». Теперь здесь же кликните по пункту «Вид». Появится дополнительное окно. В нем выберите параметр «Выбрать столбцы». Возникнет диалоговое окно, в котором самый верхний пункт будет называться «ИД процесса (pid)». Напротив него установите флажок. Сохраните настройки, нажав ОК.

Затем в диспетчере устройств пройдите во вкладку «Процессы», где вы увидите строку «ИД процесса ». Найдите в ней название процесса , идентификатор которого вам нужно узнать, и посмотрите его значение.

Теперь будет рассмотрено, это значение с помощью командной строки операционной системы. Нажмите кнопку «Пуск» и перейдите на вкладку «Все программы». Выберите «Стандартные программы». Здесь найдите пункт меню «Командная строка» и запустите его. Введите tasklist и нажмите клавишу Enter. После активации этой команды в окне командной строки появится список всех активных на данный момент процессов. После имени каждого из них будет написан его идентификатор.

Если вам необходимо быстро завершить процесс, то сделать это можно так. После того как вы узнаете идентификатор процесса , наберите в командной строке taskkill /pid 0000. Вместо нулей введите число идентификатора процесса , который требуется « ». После этого система отправит сигнал на его завершение, и он будет выключен.

Обратите внимание

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

Обращение к почтовым серверам в программе The Bat! (как и в других почтовых программах) происходит через определенные порты для отправки и приема почты. Чтобы настроить работу почтовой программы, вам надо внести в параметры ящика номера портов SMTP и POP3, а также названия серверов.

Вам понадобится

  • - данные от почты.

Инструкция

Зайдите на сайт вашего почтового сервера. Например, ваш почтовый сервер mail.ru. Вам потребуется авторизоваться - то есть ввести логин и пароль, - чтобы войти в личный почтовый ящик. Найдите ссылку на помощь и кликните по ней мышью.

Список разделов помощи находится слева. Кликните по надписи «Доступ из почтовых программ» и выберите первый пункт, чтобы загрузить страницу настроек. На странице указано, что название сервера входящей почты - pop.mail.ru, а сервера исходящей - smtp.mail.ru. Это относится только к данному сервису. Как правило, у каждого постового сервера могут быть разные порты, поэтому заходите на официальный сайт в центр поддержки и узнавайте данные. Также существуют в интернете сайты, которые предоставляют информацию практически по всем сервисам, которые существуют в интернете.

Номера портов серверов исходящей и входящей почты указаны внизу страницы. Там указано, что для сервера входящей почты протоколы имеют номера 110 (если почтовая программа работает без шифрования) и 995 (с шифрованием). Чтобы узнать, какую именно цифру вводить, изучите настройки вашей почтовой программы. Номер порта исходящей почты - 25, 587 или 2525 (если почтовая программа не использует шифрование) и 465 (с шифрованием). Стандартными почтовыми портами считаются 110 и 25. В программе также могут быть по умолчанию прописаны стандартные номера портов, поэтому при необходимости вам нужно будет их исправить на правильные.

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

TCP/IP – это совокупность протоколов , которая позволяет соединить индивидуальные компьютеры и сети в общую вычислительную сеть. При помощи протоколов TCP/IP большинство прикладных программ обмениваются информацией в сети Internet.

Как бы там ни было, но некоторые приложения в Linux иногда зависают. При этом бывают ситуации, когда приложение вообще не отзывается, либо работает так медленно, что корректно завершить его работу не представляется возможным. Чтобы оперативно выйти из получившейся ситуации можно «убить» данный процесс. Для этог используеются команды kill и killall . Сейчас мы разберемся как использоваться эти команды, находить PID процесса и посылать сигнал SIGKILL.

Чтобы избежать путацины, договоримся под процессом понимать запущенную в систему программу. Например, если у вас запушено несколько окон браузера Mozilla Firefox — это значит, что запущено три процесса.

Определить PID процесса — команда pidof

PID — уникальный идентификатор процесса в системе Linux . Чтобы корректно выполнить остановку процесса сначала стоит определить его PID. Для этого используются команды ps и grep. В свою очередь команда ps предназначена для вывода списка активных процессов в системе и информации о них. Команда grep запускается одновременно с ps (в канале) и будет выполнять поиск по результатам команды ps. Вывести список всех процессов можно, выполнив в командной строке:

Разумеется, PID можно определить и через top . Но в большинстве случаев количество процессов слишком велико (и динамически меняется в top), поэтому быстро и правильно определить PID не так уж и просто. Как раз для этого используется команда grep. Например, для завершения процесса браузера Google Chrome необходимо выполнить следующую команду:

ps axu | grep chrome

[ ////// ~]$ ps axu | grep chrome
itechf2 20474 2.7 1.5 938416 120136 tty2 Sl+ 11:07 0:00 /opt/google/chrome/chrome

В нашем случае 20474 и есть искомый PID. Более простой способ — использовать команду pidof , при этом необходимо указывать имя процесса. Например:

[ ///// ~]$ pidof chrome
20728 20706 20668 20647 20586 20574 20553 20508 20474

Завершить процесс в Linux — команды kill и killall

Завершить процесс в операционной системе Linux , зная его PID, можно командой kill . Стоит знать и понимать: команда kill предназначена для посылки сигнала процессу. По умолчанию, если мы не указываем какой сигнал посылать, посылается сигнал SIGTERM (от слова termination - завершение). SIGTERM указывает процессу на то, что необходимо завершиться. Каждый сигнал имеет свой номер. SIGTERM имеет номер 15. Список всех сигналов (и их номеров), которые может послать команда kill, можно вывести, выполнив kill -l . Чтобы послать сигнал SIGKILL (он имеет номер 9) процессу 2811, выполните в командой строке:

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

Команда killall в Linux предназначена для «убийства» всех процессов, имеющих одно и то же имя. Это удобно, так как нам не нужно знать PID процесса. Например, мы хотим закрыть все процессы с именем chrome. Выполните в терминале:

Команда killall, также как и kill, по умолчанию шлет сигнал SIGTERM. Чтобы послать другой сигнал нужно воспользоваться опцией -s . Например:



В этой статье мы попытаемся создать модуль ядра, способный изменить PID уже запущенного процесса в ОС Linux, а так же поэкспериментировать с процессами, получившими измененный PID.


Предупреждение : смена PID - нестандартный процесс, и при определенных обстоятельствах может привести к панике ядра.

Наш тестовый модуль будет реализовывать символьное устройство /dev/test, при чтении с которого процессу будет изменен PID. За пример реализации символьного устройства спасибо этой статье. Полный код модуля приведен в конце статьи. Конечно, самым правильным решением было добавить системный вызов в само ядро, однако это потребует перекомпиляцию ядра.

Окружение

Все действия по тестированию модуля выполнялись в виртуальной машине VirtualBox с 64 битным дистрибутивомLInux и версией ядра 4.14.4-1. Связь с машиной осуществлялась с помощью SSH.

Попытка #1 простое решение

Пару слов о current : переменная current указывает на структуру task_struct с описанием процесса в ядре(PID, UID, GID, cmdline, namespaces и т.д)

Первой идеей было просто поменять параметр current->pid из модуля ядра на нужный.

Static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset) { printk("PID: %d.\n",current->pid); current->pid = 1; printk("new PID: %d.\n",current->pid); , }
Для проверки работоспособности модуля я написал программу на C++:

#include #include #include int main() { std::cout << "My parent PID " << getppid() << std::endl; std::cout << "My PID " << getpid() << std::endl; std::fstream f("/dev/test",std::ios_base::in); if(!f) { std::cout << "f error"; return -1; } std::string str; f >> str; std::cout << "My new PID " << getpid() << std::endl; execl("/bin/bash","/bin/bash",NULL); }
Загрузим модуль коммандой insmod, создадим /dev/test и попробуем.

# ./a.out My parent PID 293 My PID 782 My new PID 782
PID не изменился. Возможно, это не единственное место, где указывается PID.

Попытка #2 дополнительные поля PID

Если не current->pid является идентификатором процесса, то что является? Быстрый просмотр кода getpid() навел на структуру task_struct , описывающую процесс Linux и файл pid.c в исходном коде ядра. Нужная функция - __task_pid_nr_ns. В коде функции встречается обращение task->pids.pid, этот параметр мы и изменим

Компилируем, пробуем

Так как тестировал я по SSH, мне удалось получить вывод программы до падения ядра:

My parent PID 293 My PID 1689 My new PID 1689
Первый результат, уже что-то. Но PID все равно не изменился.

Попытка #3 не экспортируемые символы ядра

Более внимательное изучение pid.c дало функцию, которая делает то, что нам нужно
static void __change_pid(struct task_struct *task, enum pid_type type,
struct pid *new)
Функция принимает задачу, для которой надо изменить PID, тип PID и, собственно, новый PID. Созданием нового PID занимается функция
struct pid *alloc_pid(struct pid_namespace *ns)

Эта функция принимает только пространство имен, в котором будет находиться новый PID, это пространство можно получить с помощью task_active_pid_ns .
Но есть одна проблема: эти символы ядра не экспортируются ядром и не могут использоваться в модулях. В решении этой проблемы мне помогла замечательная . Код функции find_sym взят оттуда.

Static asmlinkage void (*change_pidR)(struct task_struct *task, enum pid_type type, struct pid *pid); static asmlinkage struct pid* (*alloc_pidR)(struct pid_namespace *ns); static int __init test_init(void) { printk(KERN_ALERT "TEST driver loaded!\n"); change_pidR = find_sym("change_pid"); alloc_pidR = find_sym("alloc_pid"); ... } static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset) { printk("PID: %d.\n",current->pid); struct pid* newpid; newpid = alloc_pidR(task_active_pid_ns(current)); change_pidR(current,PIDTYPE_PID,newpid); printk("new PID: %d.\n",current->pid); ... }
Комплируем, запускаем

My parent PID 299 My PID 750 My new PID 751
PID изменен! Ядро автоматически выделило нашей программе свободный PID. Но можно ли использовать PID, который занял другой процесс, например PID 1? Добавим после аллокации код

Newpid->numbers.nr = 1;
Комплируем, запускаем

My parent PID 314 My PID 1172 My new PID 1
Получаем настоящий PID 1!

Bash выдал ошибку, из-за которой не будет работать переключение задач по комманде %n, но все остальные функции работают отлично.

Интересные особенности процессов с измененным PID

PID 0: войти нельзя выйти

Вернемся к коду и изменим PID на 0.

Newpid->numbers.nr = 0;
Комплируем, запускаем

My parent PID284 My PID 1517 My new PID 0
Выходит PID 0 не такой и особенный? Радуемся, пишм exit и…

Ядро падает! Ядро определило нашу задачу как IDLE TASK и, увидев завершение, просто упало. Видимо, перед завершением наша программа должна вернуть себе «нормальный» PID.

Процесс-невидимка

Вернемся к коду и выставим PID, гарантированно не занятый
newpid->numbers.nr = 12345;

Комплируем, запускаем

My parent PID296 My PID 735 My new PID 12345
Посмотрим, что находится в /proc

1 148 19 224 288 37 79 86 93 consoles fb kcore locks partitions swaps version 10 149 2 226 29 4 8 87 acpi cpuinfo filesystems key-users meminfo sched_debug sys vmallocinfo 102 15 20 23 290 5 80 88 asound crypto fs keys misc schedstat sysrq-trigger vmstat 11 16 208 24 291 6 81 89 buddyinfo devices interrupts kmsg modules scsi sysvipc zoneinfo 12 17 21 25 296 7 82 9 bus diskstats iomem kpagecgroup mounts self thread-self 13 176 210 26 3 737 83 90 cgroups dma ioports kpagecount mtrr slabinfo timer_list 139 18 22 27 30 76 84 91 cmdline driver irq kpageflags net softirqs tty 14 182 222 28 31 78 85 92 config.gz execdomains kallsyms loadavg pagetypeinfo stat uptime
Как видим /proc не определяет наш процесс, даже если мы заняли свободный PID. Предыдущего PID тоже нет в /proc, и это весьма странно. Возможно, мы находимся в другом пространстве имен и поэтому не видны основному /proc. Смонтируем новый /proc, и посмотрим что там

1 14 18 210 25 291 738 81 9 bus devices fs key-users locks pagetypeinfo softirqs timer_list 10 148 182 22 26 296 741 82 90 cgroups diskstats interrupts keys meminfo partitions stat tty 102 149 19 222 27 30 76 83 92 cmdline dma iomem kmsg misc sched_debug swaps uptime 11 15 2 224 28 37 78 84 93 config.gz driver ioports kpagecgroup modules schedstat sys version 12 16 20 226 288 4 79 85 acpi consoles execdomains irq kpagecount mounts scsi sysrq-trigger vmallocinfo 13 17 208 23 29 6 8 86 asound cpuinfo fb kallsyms kpageflags mtrr self sysvipc vmstat 139 176 21 24 290 7 80 87 buddyinfo crypto filesystems kcore loadavg net slabinfo thread-self zoneinfo
По прежнему нашего процесса нет, а значит мы в обычном пространстве имен. Проверим

Ps -e | grep bash
296 pts/0 00:00:00 bash

Только один bash, с которого мы и запускали программу. Ни предыдущего PID, ни текущего в списке нет.

В этой статье мы попытаемся создать модуль ядра, способный изменить PID уже запущенного процесса в ОС Linux, а так же поэкспериментировать с процессами, получившими измененный PID.


Предупреждение : смена PID - нестандартный процесс, и при определенных обстоятельствах может привести к панике ядра.

Наш тестовый модуль будет реализовывать символьное устройство /dev/test, при чтении с которого процессу будет изменен PID. За пример реализации символьного устройства спасибо этой статье. Полный код модуля приведен в конце статьи. Конечно, самым правильным решением было добавить системный вызов в само ядро, однако это потребует перекомпиляцию ядра.

Окружение

Все действия по тестированию модуля выполнялись в виртуальной машине VirtualBox с 64 битным дистрибутивомLInux и версией ядра 4.14.4-1. Связь с машиной осуществлялась с помощью SSH.

Попытка #1 простое решение

Пару слов о current : переменная current указывает на структуру task_struct с описанием процесса в ядре(PID, UID, GID, cmdline, namespaces и т.д)

Первой идеей было просто поменять параметр current->pid из модуля ядра на нужный.

Static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset) { printk("PID: %d.\n",current->pid); current->pid = 1; printk("new PID: %d.\n",current->pid); , }
Для проверки работоспособности модуля я написал программу на C++:

#include #include #include int main() { std::cout << "My parent PID " << getppid() << std::endl; std::cout << "My PID " << getpid() << std::endl; std::fstream f("/dev/test",std::ios_base::in); if(!f) { std::cout << "f error"; return -1; } std::string str; f >> str; std::cout << "My new PID " << getpid() << std::endl; execl("/bin/bash","/bin/bash",NULL); }
Загрузим модуль коммандой insmod, создадим /dev/test и попробуем.

# ./a.out My parent PID 293 My PID 782 My new PID 782
PID не изменился. Возможно, это не единственное место, где указывается PID.

Попытка #2 дополнительные поля PID

Если не current->pid является идентификатором процесса, то что является? Быстрый просмотр кода getpid() навел на структуру task_struct , описывающую процесс Linux и файл pid.c в исходном коде ядра. Нужная функция - __task_pid_nr_ns. В коде функции встречается обращение task->pids.pid, этот параметр мы и изменим

Компилируем, пробуем

Так как тестировал я по SSH, мне удалось получить вывод программы до падения ядра:

My parent PID 293 My PID 1689 My new PID 1689
Первый результат, уже что-то. Но PID все равно не изменился.

Попытка #3 не экспортируемые символы ядра

Более внимательное изучение pid.c дало функцию, которая делает то, что нам нужно
static void __change_pid(struct task_struct *task, enum pid_type type,
struct pid *new)
Функция принимает задачу, для которой надо изменить PID, тип PID и, собственно, новый PID. Созданием нового PID занимается функция
struct pid *alloc_pid(struct pid_namespace *ns)

Эта функция принимает только пространство имен, в котором будет находиться новый PID, это пространство можно получить с помощью task_active_pid_ns .
Но есть одна проблема: эти символы ядра не экспортируются ядром и не могут использоваться в модулях. В решении этой проблемы мне помогла замечательная . Код функции find_sym взят оттуда.

Static asmlinkage void (*change_pidR)(struct task_struct *task, enum pid_type type, struct pid *pid); static asmlinkage struct pid* (*alloc_pidR)(struct pid_namespace *ns); static int __init test_init(void) { printk(KERN_ALERT "TEST driver loaded!\n"); change_pidR = find_sym("change_pid"); alloc_pidR = find_sym("alloc_pid"); ... } static ssize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset) { printk("PID: %d.\n",current->pid); struct pid* newpid; newpid = alloc_pidR(task_active_pid_ns(current)); change_pidR(current,PIDTYPE_PID,newpid); printk("new PID: %d.\n",current->pid); ... }
Комплируем, запускаем

My parent PID 299 My PID 750 My new PID 751
PID изменен! Ядро автоматически выделило нашей программе свободный PID. Но можно ли использовать PID, который занял другой процесс, например PID 1? Добавим после аллокации код

Newpid->numbers.nr = 1;
Комплируем, запускаем

My parent PID 314 My PID 1172 My new PID 1
Получаем настоящий PID 1!

Bash выдал ошибку, из-за которой не будет работать переключение задач по комманде %n, но все остальные функции работают отлично.

Интересные особенности процессов с измененным PID

PID 0: войти нельзя выйти

Вернемся к коду и изменим PID на 0.

Newpid->numbers.nr = 0;
Комплируем, запускаем

My parent PID284 My PID 1517 My new PID 0
Выходит PID 0 не такой и особенный? Радуемся, пишм exit и…

Ядро падает! Ядро определило нашу задачу как IDLE TASK и, увидев завершение, просто упало. Видимо, перед завершением наша программа должна вернуть себе «нормальный» PID.

Процесс-невидимка

Вернемся к коду и выставим PID, гарантированно не занятый
newpid->numbers.nr = 12345;

Комплируем, запускаем

My parent PID296 My PID 735 My new PID 12345
Посмотрим, что находится в /proc

1 148 19 224 288 37 79 86 93 consoles fb kcore locks partitions swaps version 10 149 2 226 29 4 8 87 acpi cpuinfo filesystems key-users meminfo sched_debug sys vmallocinfo 102 15 20 23 290 5 80 88 asound crypto fs keys misc schedstat sysrq-trigger vmstat 11 16 208 24 291 6 81 89 buddyinfo devices interrupts kmsg modules scsi sysvipc zoneinfo 12 17 21 25 296 7 82 9 bus diskstats iomem kpagecgroup mounts self thread-self 13 176 210 26 3 737 83 90 cgroups dma ioports kpagecount mtrr slabinfo timer_list 139 18 22 27 30 76 84 91 cmdline driver irq kpageflags net softirqs tty 14 182 222 28 31 78 85 92 config.gz execdomains kallsyms loadavg pagetypeinfo stat uptime
Как видим /proc не определяет наш процесс, даже если мы заняли свободный PID. Предыдущего PID тоже нет в /proc, и это весьма странно. Возможно, мы находимся в другом пространстве имен и поэтому не видны основному /proc. Смонтируем новый /proc, и посмотрим что там

1 14 18 210 25 291 738 81 9 bus devices fs key-users locks pagetypeinfo softirqs timer_list 10 148 182 22 26 296 741 82 90 cgroups diskstats interrupts keys meminfo partitions stat tty 102 149 19 222 27 30 76 83 92 cmdline dma iomem kmsg misc sched_debug swaps uptime 11 15 2 224 28 37 78 84 93 config.gz driver ioports kpagecgroup modules schedstat sys version 12 16 20 226 288 4 79 85 acpi consoles execdomains irq kpagecount mounts scsi sysrq-trigger vmallocinfo 13 17 208 23 29 6 8 86 asound cpuinfo fb kallsyms kpageflags mtrr self sysvipc vmstat 139 176 21 24 290 7 80 87 buddyinfo crypto filesystems kcore loadavg net slabinfo thread-self zoneinfo
По прежнему нашего процесса нет, а значит мы в обычном пространстве имен. Проверим

Ps -e | grep bash
296 pts/0 00:00:00 bash

Только один bash, с которого мы и запускали программу. Ни предыдущего PID, ни текущего в списке нет.

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

Идентификатор родительского процесса (ррid)

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

Исходный процесс в терминологии ОС UNIX называют родительским, а его клон – порожденным. Помимо собственного идентификатора, каждый процесс имеет атрибут РРID, т.е. идентификатор своего родительского процесса.

Идентификатор пользователя (uid) и эффективный идентификатор пользователя (euid)

UID – это идентификационный номер пользователя, создавшего данный процесс. Вносить изменения в процесс могут только его создатель и привилегированный пользователь. Система учета относит на счет создателя процесса все ресурсы, которые использует его процесс.

EUID– это «эффективный»UIDпроцесса. ЕUIDиспользуется для того, чтобы определить, к каким ресурсам и файлам у процесса есть право доступа. У большинства процессовUIDи ЕUID будут одинаковыми. Исключение составляют программы, у которых установлен бит смены идентификатора пользователя (см. обSUIDв разделе, посвященном установлению прав доступа на файлы и каталоги).

Идентификатор группы (gid) и эффективный идентификатор группы (egid)

GID– это идентификационный номер группы данного процесса. Допустимые идентификаторы групп указываются в файле/ etc / group и в поле GID файлаtc / passwd . Когда процесс запускается, егоGIDустанавливается равнымGIDродительского процесса.

EGIDсвязан сGIDтак же, как ЕUIDсUID. Если процесс попытается обратиться к файлу, на который не имеет прав владельца, ядро автоматически проверит, можно ли предоставлять разрешение на основании данного ЕEGID.

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

Приоритет и значениеnice

От приоритета процесса зависит, какую часть времени центрального процессора он получит. Выбирая процесс для выполнения, ядро находит процесс с самым высоким «внутренним приоритетом».

Непосредственно установить внутренний приоритет невозможно, но можно установить так называемое значение nice, которое существенно влияет на внутренний приоритет. Кроме того, внутренний приоритет зависит от того, сколько времени центрального процессора уже использовал процесс и от времени ожидания своей очереди на выполнение.

Жизненный цикл процесса

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

Для создания нового процесса существующий процесс копирует самого себя с помощью системного вызова fork. Вызовforkсоздает копию исходного процесса, идентичную родителю, но имеющую следующие отличия:

    у нового процесса свой PID;

    PPIDнового процесса равенPIDродителя;

    учетная информация нового процесса обнулена;

    у нового процесса имеется свой собственный экземпляр дескрипторов файлов.

Когда система загружается, ядро самостоятельно создает несколько процессов. Наиболее важный из них – процесс (демон) init ,PIDкоторого всегда равен 1. Этот процесс отвечает за вызовshellдля выполнения сценариев запускаrc , если Ваша система их использует. Все процессы, кроме тех, которые создает ядро, являются потомкамиinit .

После обработки файлов запуска процесс init запускает для каждого виртуального терминала процессgetty .

Процесс init играет важную роль и в управлении процессами. Когда процесс завершается, он вызывает подпрограмму_ exit , чтобы уведомить ядро о своей готовности «умереть». В качестве параметра подпрограмме_ exit передаетсякод завершения – целое число, указывающее на причину завершения процесса. По соглашению нулевой код завершения означает, что процесс был «успешным».

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

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