Процессы и потоки в Linux

Данный конспект в доработке

    Процессы

    Процесс - это абстракция виртуализации
    Ядро linux предоставляет каждому процессу, многозадачность, виртуализированный процессор, виртуальную память
    Процессы - это объектный код, находящийся в процессе выполнения, который содержит в себе не только код, но и данные, ресурсы и виртуализированный процесс.
    Объектный код, понятный для исполнения на машине и ядру ( наиболее распространенный в linux формат исполняемых и компонуемых файлов ELF ) или по другому исполняемый формат содержит метаданные и множество разделов с кодом и данными
    Разделы - это линейные фрагменты объектного кода загружаемые в память, имеют одинкаковые права и цели исполнения
    Самый важный раздел - текстовый и bss
    В текстовом разделе содержатся исполняемый код и данные только для чтения, в том числе константы и переменные
    В разделе данных хранятся инициализированные переменные, обычно данный раздел доступен для чтения и записи
    Раздел bss содержит инициализированные глобальные данные
    Кроме вышеизложенного процесс ассоциирован с различными ресурсами, которые выделяются и управляются ядром. Процессы запрашивают и манипулируют ресурсами посредством системных вызовов.
    В качестве ресурсов процессора могут относиться таймеры, ожидающие сигналы, открытые файлы, сетевые соединения, аппаратное обеспечение, механизмы межпроцессорного взаимодействия
    Ресурсы процессора, данные и статистика о нем сохраняются внутри ядра в дескрипторе процессора
    Новый процессы в linux создаются с помощью системного вызова fork(). В результате этого вызова создается дубликат вызывающего процесса
    Если родительский процесс завершается раньше дочернего, то ядро переназначает предка для потомка. После завершения процесса, он какое то время еще живет в системе, ядро сохряняет фрагменты процесса в памяти, обеспечивая процессу-предку доступ к информации. Такое запрашивание называется обслуживанием завершенного процесса.
    Процесс, который уже завершился, но еще не был обслужен, называется зомби

    Потоки

    Каждый процесс состоит из одного или нескольких потоков выполнения
    Поток - это еденица активности в процессе, отвечает за выполнение кода и поддержки процесса в рабочем состоянии
    Процесс состоящий из нескольких потоков называется многопоточным
    Поток состоит из стека в котором хранятся локальные переменные, состояния процесса и местоположения в объектном коде
    Местоположение кода хранится в указателе команд процесса
    Адресное пространство делится между всеми потоками


    Нормальные процессы - это процессы переднего плана, у которых продолжительность жизни ограничивается сеансом, завершаются по истечении определенного времени или выходом пользователя, от которого был запущен процесс
    Осиротевшие процессы - процессы, которые имели родительский процесс, но по какой то причине родительский процесс был завершен непринудительно и родителем осиротевших процессов стал init процесс. Процесс init будет ждать и завершения или остановки
    Процессы демоны - независимые процессы которые намеренно сделаны осиротевшими и после инициации были отключены от контролирующего терминала(родителя), данные процессы работают в фоновом режиме, пока их задание не будет выполнено.
    Процессы хранятся в /proc/ в виде директорий, в этих директориях хранятся данные о процессе
    Например:
    /proc/1/fd - хранит дескрипторы процесса 1 (init), которые в своем большинстве являются сетевыми соединениями или принадлежат каким то файлам
    Удобнее просматривать дескрипторы процесса утилитой lsof, она выводит дополнительную информацию:

    lsof -p 1

    cwd - текущая директория процесса
    rtd - директория процесса выше которой процесс подниматься не может
    txt - бинарный файл
    .so - разделяемая библиотека(в windows dll)
    mem - адресное пространство процесса


    /proc//stat - основная информация процесса
    /proc/stat - общая информация о потреблении cpu процессами

    Команда ps

    Опции команды ps

    l Вывод результата в длинном формате u Вывод в пользовательском формате (показывает имя пользователя и время запуска) j Вывод результата в рабочем формате (показывает идентификаторы GID и SID процесса) s Вывод результата в сигнальном формате v Вывод результата в vm -формате m Отображает состояние памяти f Использует для вывода forest -формат (показывает процессы в виде дерева) a Показывает процессы других пользователей x Показывает процессы, не отображая управляющий терминал S Показывает дочерний CPU, а также время и страницу сбоев c Название команды для task_struct e Показывает состояние после командной строки и а+ w Выводит результат в расширенном формате h Не выводит заголовок r Показывает только запущенные процессы n Показывает числовой вывод для USER и WCHAN txx Показывает процессы, управляемые терминалом ttyxx O Сортирует вывод процессов по ключам к1, к2 и т.д. Pids Показывает только процессы с указанными PID
    Расшифровка всех возможных кодов состояния процесса
    D Непрерываемый, находящийся в ожидании R Выполняется S Ожидающий T Отслеживается или остановлен Z Нефункциональный процесс-"зомби" W У процесса нет страниц в памяти (процесс свопирован) < Процесс с высоким приоритетом
    N Процесс с низким приоритетом L Некоторые страницы оперативной памяти блокированы

    Процессы заключенные в квадратные скобки - это которые вследствие низкой активности были перекачаны из памяти в пространство подкачки на жестком диске

    top

    Load Average (LA ) рассчитывается как среднее значение загрузки системы за определённый период времени. Как правило, это усреднённые величины за последние 1, 5 и 15 минут
    Пример: load average: 0.08, 0.04, 0.05
    LA высчитывается на основании процессов, которые выполняются и находятся в очереди на выполнение (CPU, RAM, I/O)
    В многоядерной (многопроцессорной) системе значения Load Average (LA) рассчитываются пропорционально числу ядер
    LA нужно сравнивать с количеством ядер процессора. LA = 2 на 2-ядерном процессоре — это высокая загрузка, а LA = 2 на 8-ядерном — вполне нормальная нагрузка.
    Для четырёхядерной системы LA 15 не должен превышать 3,00, для двухядерной — 1,5, а для одноядерной — 0,75
    В выводе утилиты top:
    us - процессорное время потребляемое приложениями
    sy - время потребляемое системой
    ni - время потребляемое пользовательскими процессами с низким приоритетом
    id - время в процентах которое не потребляется, этот показатель должен быть высоким
    wa - время операций ввода вывода. Высокий показатель означает, что процессор очень долго ждет ответы от устройств ввода/вывода. Чаще всего это связано с большим количеством операций на диске.
    hi si - время на обработку аппаратных и программных прерываний
    st - время затраченное виртуальной машиной


    Команды top

    M — сортировка по используемой памяти
    P — сортировка по нагрузке на процессор (используется по умолчанию)
    T — сортировка по времени работы процесса
    A — сортировка по максимальному потреблению различных ресурсов
    u — сортировка по имени пользователя (потребуется ввести имя пользователя)
    k — завершить процесс (потребуется указать его идентификатор, PID)
    n — изменить количество процессов в выводе (потребуется указать нужное количество)
    c — вывести полный путь запущенного процесса


    Более подробно узнать о /proc можно с помощью команды man

    man proc
    strace
    strace ls

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


    Второй вариант использования утилиты это подстановка номера процесса:

    strace -p 1

    Следующая опция -с команды покажет в реальном времени какие системные вызовы использует процесс

    strace -c -p 1
    Сигналы

    Сигналы - это механизм, который обеспечивает односторонние асинхронные уведомления.
    Сигнал может быть отправлен от ядра к процессу, от процесса к другому процессу, от процесса к самому себе
    Сигнал может сообщать процессу о каком либо событии, например пользователь нажал ctrl+c или возникла ошибка сегментации памяти


    Ядро linux реализует около 30 разновидностей сигналов, зависит от архитектуры продукта
    Сигналы прерывают исполнение работающего процесса
    Все сигналы за исключением SIGKILL и SIGSTOP, оставляют процессам выбор действий
    Если сигнал не игнорируется, тогда происходит обработка сигнала обработчиком сигнала, после чего контроль переходит обратно инструкции, которая была прервана

    CTRL+C = SIGINT и SIGQUIT
    kill по умолчанию отправляет процессу сигнал SIGTERM, который как SIGINT или SIGQUIT могут быть перехвачены процессом и не дать нужного результата
    Следующие две команды эквивалентны:
    kill -9 2700
    kill -KILL 2700
    Но даже при явном указании сигнала ( в редких случаях ) процесс не исчезает. Такое возможно если процесс уже завершился, но все еще остается в системе, потому как его предок по какой то причине отказался затребовать у ОС подтверждение о завершении. Зомби убить нельзя, он уже мертвый, если только не убить его предка
    Процесс зомби не потребляет ресурсы системы, но остается в таблице процессов
    Другая причина. Процесс мог выполнить системный вызов ( обратился к ОС за определенной услугой ) в ходе выполнения которого система перевела процесс в состояние непрерывного сна. Если процесс не выходит из этого состояния, возможно есть проблемы с устройством, например испорченный диск и вывести процесс из такого состояния невозможно
    Процесс зомби помечается буквой Z ( defunct )
    Процесс состояния "Непрерывного сна" помечается буквой D ( badblocks )

    Сигналы управления процессами

    Доп. информация man signal
    Список всех сигналов:

    $ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX
    Лимит процессов

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


    Лимит выделяется не конкретного процесса, а на все процессы пользователя
    Какие лимиты существуют:

    ulimit -a

    Для управления лимитами существует файл /etc/security/limits.conf
    В нем два вида лимита soft или hard мягкие и жесткие

    Переменные окружения

    /proc/pid/environ
    Переменные окружения динамически изменяемый набор ключей и значений относящихся к конкретному процессу.
    Если при написании приложении необходимо задействовать свою собственную библиотеку функций, можно использовать переменную окружения LD_PRElOAD чтобы указать путь к библиотеке и путь к запуску приложения. Сначала будет загружена библиотека, затем приложение
    Еще одна важная системная переменная LD_LIBRARY_PATH
    Задать переменную окружения export FOO=....


    Лимит PID
    Остановить зомби апокалипсис

    pstack

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

    pstack

    Альтернатива gdb. Есть возможность установить дополнительную библиотеку для отладки glibc-debuginfo

    perf
    Утилита ipcs

    ipcs -m - используется для просмотра текущих сегментов памяти с совместным доступом

    pidof

    Возвращает идентификатор процесса (pid) по его имени

    pstree

    Вывод исполняющихся процессов в виде дерева

    jobs

    jobs - выводит список заданий, исполняющихся в фоне, однако команда ps более информативна
    Такие команды как kill, disown, wait принимают в качестве параметра номер процесса или номер задания
    Команды fg, bg, jobs принимают в качестве параметра, только номер задания

    ~$ sleep 100 & [1] 4848 ~$ jobs [1]+ Запущен sleep 100 & disown 4848

    [1] - номер задания
    4848 - номер процесса
    disown - удаляет задание из таблицы активных заданий командной оболочки
    fg - переводит задания из фона в консоль
    bg перезапускает приостановленное задание в фоновом режиме


    Источники
    Последнее изменение: 25.12.2024 07:20


    Связанные темы
    Здесь пока нет комментариев
    Добавлять комментарии могут только авторизованные пользователи

    Авторизоваться
    Я буду рекламой
    Я тоже буду рекламой
    И я
    ВВЕРХ