Processos no UNIX(R) e GNU/Linux

Processos no UNIX(R) e GNU/Linux

Em sistemas UNIX e Linux um processo é uma abstração utilizada para representar um programa em execução. Pelo uso e tempo de CPU, memória, recurso de E/S e I/O, podemos monitorar o uso desses processos através do seu "process id", ou PID. No sistema ele é identificado e monitorado constantemente pelo kernel e pelo administrador de sistema através de diversos utilitários ou ferramentas para isso.

Um dos melhores e mais conhecidos comandos para visualizar o status dos processos no mundo UNIX e Linux é o comando ps ou "Process Status". Eu pessoalmente nao gosto de utilitários como o top e htop, apesar deles serem bastante intuitivos e atraentes, existem alguns outros que também valem a sua consideração como o atop, vtop, btop++ (esse é fantastico), nmon, ytop, o bom e velho glance que você encontra em sistemas como HP-UX, AIX,Tru64 e até mesmo no Linux.

Porem, de todos estes que eu citei ai em cima, ainda sim, a maneira que o ps faz para extrair informações de um processo é suficiente para administrar um bom sistema Unix e Linux.

Basicamente suas opções são estas:

# ps <opções>
  u Infomrações sobre os usuarios do processo 
incluindo informações como $USER, UID, %CPU, %MEM, VSZ, RSS e START.
  x Exibe processos que não estão relacionados a algum terminal.
  f Exibe os processos no formato floresta, incluindo o PPID e o PID.
  w Exibe os processos da forma não encurtada.
  p exibe informações de um processo específico.
  o especifica o formato de saida, personalizando o output do comando ps. 
Por exemplo, existe a possibilidade de adcionar colunas com informações,
tais como do pid,cpu,mem,ppid,comando executado,processo,usuario que executou e muitas outras coisas.

Alguns comandos interessantes dele são:

[root@poder ~]# ps -eo pid,ppid,user,comm,cmd,%cpu,%me
    PID    PPID USER     COMMAND         CMD                         %CPU %MEM
      1       0 root     systemd         /usr/lib/systemd/systemd --  0.1  0.1
      2       0 root     kthreadd        [kthreadd]                   0.0  0.0
      3       2 root     rcu_gp          [rcu_gp]                     0.0  0.0
      4       2 root     rcu_par_gp      [rcu_par_gp]                 0.0  0.0
      6       2 root     kworker/0:0H-ev [kworker/0:0H-events_highpr  0.0  0.0
      9       2 root     mm_percpu_wq    [mm_percpu_wq]               0.0  0.0
     10       2 root     rcu_tasks_rude_ [rcu_tasks_rude_]            0.0  0.0
     11       2 root     rcu_tasks_trace [rcu_tasks_trace]            0.0  0.0
     12       2 root     ksoftirqd/0     [ksoftirqd/0]                0.0  0.0
... output foi cortado

A maneira mais tradicional de todas:

[root@poder ~]# ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           2  0.0  0.0      0     0 ?        S    18:52   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   18:52   0:00  \_ [rcu_gp]
root           4  0.0  0.0      0     0 ?        I<   18:52   0:00  \_ [rcu_par_gp]
root           5  0.0  0.0      0     0 ?        I    18:52   0:00  \_ [kworker/0:0-cgroup_pidlist_destroy]
root           6  0.0  0.0      0     0 ?        I<   18:52   0:00  \_ [kworker/0:0H-events_highpri]
root           7  0.0  0.0      0     0 ?        I    18:52   0:00  \_ [kworker/0:1-cgroup_destroy]
.... output foi cortadof

Nesse resultado você encontra informações como:

  • Nome do usuário que iniciou o processo.

  • Numero do processo.

  • Porcentagem do consumo do CPU por aquele processo.

  • Porcentagem da memoria física que o processo esta usando.

  • o VSZ que é o tamanho da memoria virtual que esta sendo utilizada pelo processo em kilobytes, incluindo a memoria compartilhada por ele.

  • o RSS, que é o tamanho residente e real da memoria usada pelo processo em kilobytes (essa informação exclui o uso o uso da memoria compartilhada)

  • TTY, que define o terminal que o processo esta sendo executado. Se aparecer "?", é pq não esta associado a nenhum terminal.

  • STAT que define o estado do processo. Ou seja: R (rodando), S (interrompido! Dormindo! Só de olho e aguardando a conclusão de um evento, rsrs), D (dormindo, bloqueado), Z (zumbi, processo finalizado, mas ainda na tabela de processos enchendo a paciência), T (parado, porem quando t minúsculo pode identificar um processo em debug durante um tracing).

  • START, horário de inicio do processo.

  • TIME, Tempo de CPU usado pelo processo.

  • COMMAND, que é o nome do comando que iniciou o processo. (Espere altas emoções aqui ....)

Uma observação no Linux, nesse output do comando ps acima vc vai encontrar processos em colchetes, na maioria dos casos em 99%, são processos relacionados a módulos do kernel como o kthreadd e kworker/0.

Vale a pena lembrar que o comando ps extrai todas as informações dos processos do sistema que estão sendo executados, quase como uma fotografia. Porém, essa informação pode ser extraída com "-" ou sem o "menos", dependendo da sua opção. Por exemplo, o comando ps aux terá o mesmo resultado que ps -aux, mas não acontecerá o mesmo com o comando ps -ef para ps ef. O que muda o formato de uso do traço ou não é o modelo utilizado no seu desenvolvimento do bom e velho BSD para o formato UNIX SystemV.

No caso do Linux ele usa o modelo de conceito escrito pelo projeto GNU, ou seja, sem o traço. Talvez ai no MacOS vc seja obrigado a usar o "-", assim como em outros sistemas operacionais. Ou talvez não. Mas isso não importa! O formato encontrado no Linux, ou seja, oferecido pelo projeto GNU através do procps-ng e do GNU Core Utilities (gnucoreutils), vc terá todos os tipos e gostos para os resultados gerados pelo comando ps e de outros comandos, como um simples ls.

Mas existem diferenças dos comandos "core" do GNU/Linux para UNIX(R)? SIM e como!! Todos os comandos que vc encontra em procps, findutils e coreutils são bem diferentes em diversos sistemas UNIX. Por exemplo, no AIX para visualizar partições montadas e quanto elas estão consumindo em "GB", vc usa o df -sg e no Linux um simples df -h.

O interessante do comando ps no Linux, assim como muitos sistemas UNIX é que ele extrai todas as informações dos processos utilizando o diretório /proc como critério, ou especificamente do /proc/<PID> em arquivos lá dentro como status, cmdline, stat, statm, meminfo e cpuinfo.

Mas o que é o /proc? Ele é um sistema de arquivos virtual chamado de procfs, que é criado toda vez que vc da um boot no sistema operacional, sendo atualizado constantemente durante o uso do OS e que fornece todas as informações sobre processos que estão ativos no sistema. No Linux, ele também fornece informações do hardware, extraindo um inventário durante o boot e isso é bem diferente no mundo UNIX. Ele coleta a todo momento informações do sistema operacional como: processos em execução, informações sobre os dispositivos adicionados no sistema, informações sobre a utilização de memoria e cpu, tal como informações sobre os sistemas de arquivos utilizados e como estatísticas de I/O deles. Tudo em um grande pseudo-filesystem criado de maneira virtual pelo próprio kernel.

Para cada processo ativo no sistema, ele vai receber um PID que será automaticamente disponibilizado em /proc com informações e caracteristicas deste processo.

Alguns arquivos são:

Não foi fornecido texto alternativo para esta imagem

Imagem retirada do site do kernel (material da versão 2.4, mas sempre de bom grado)

Essa imagem acima eu tirei do site do próprio kernel em The /proc Filesystem — The Linux Kernel documentation e já antecipo que se você é um apaixonado pelo kernel Linux como eu, vai encontrar um mundo de informações ali sobre processos como o conteúdo e descrição dos processos encontrados nos arquivos mencionados acima.

Mas gostaria de pontuar algumas coisas interessantes da imagem acima.

Por exemplo. Digamos que eu abri um programa e ele esta agora em execução no meu sistema. O kernel entregou a ele o PID de número 20200 e armazenou no procfs em /proc/20200. No meio de tantos arquivos que podemos encontrar la dentro, um deles é o arquivo wchan, que exibe o nome da função do kernel em que o processo está aguardando. No meu exemplo aqui eu tive um core_sys_select, ou seja, isso me diz que este processo que eu estava analisando está aguardando a conclusão de uma chamada de sistema que esta registrando uma I/O no meu disco. Por exemplo, esperando por uma resposta de um dispositivo de armazenamento? Ele tambem poderia me informar um "poll_schedule_timeout" que diz que o processo esta aguardando uma chamada poll() do kernel, ou seja, usada para monitorar o estado das entradas de E/S, tudo organizado pelo kernel, como arquivos, soquetes e pipes. Ou até mesmo me dizer que o processo esta "dormindo" ou "sched:sleep". Enfim, muita coisa apenas com um único arquivo.

Mas eu tambem poderia utilizar o procfs para verificar qual o comando utilizado para executar esse "process id" ou processo. Então, verificando os arquivos /proc/20200/comm ou /proc/20200/cmdline ele me informa o nome do programa/processo.

cat /proc/494/comm
top

cat /proc/494/cmdline
top

O arquivo status contém informações completas elevadas ao quadrado do uso de memoria do processo, tais como:

  • nome do processo

  • estado dele, se esta executando, suspenso ou esperando.

  • o tgid que é o grupo de threads do processo.

  • O PID do processo e seu processo pai (PPID)

  • Informações do usuário que executou, como UID e GID.

  • VmPeak, que é o pico de memoria virtual do processo em uso.

  • VmSize, que é o tamanho total da memoria virtual usada pelo processo.

  • VmLck, que fornece o tamanho do da memoria em "locked" do processo. Isso significa que essa memoria fica reservada ou fixada em algum lugar da sua RAM (tadinha), e isso impede que ela seja movida para a área de SWAP. Isso é muitooooooooo maneiro, pq isso garante que alguns dados armazenados na memória, que são críticos para o processo, permaneçam sempre disponíveis para a memória física, sem que nenhum outro processo o roube a área ou acesse essa informação valorosa.

  • VmRSS, que é o tamanho real da memoria do processo (resident set size).

  • Threads, que é o número de threads do processo em execução

e muitas outras coisas... se eu escrever todas vão dar um livro.........................

# cat /proc/494/status
Name:   top
Umask:  0022
State:  T (stopped)
Tgid:   494
Ngid:   0
Pid:    494
PPid:   120
TracerPid:      0
Uid:    0       0       0       0
Gid:    0       0       0       0
FDSize: 256
Groups: 0 1001
NStgid: 494
NSpid:  494
NSpgid: 494
NSsid:  120
VmPeak:    52128 kB
VmSize:    52108 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:      4196 kB
VmRSS:      4196 kB
RssAnon:             672 kB
RssFile:            3524 kB
RssShmem:              0 kB
VmData:     1020 kB
VmStk:       132 kB
VmExe:       108 kB
VmLib:      6824 kB
VmPTE:       140 kB
VmSwap:        0 kB
... output cortado pq o bichinho é bem grande. O poder!

Outro arquivo que auxilia muito os administradores de sistema é o stat, que também se encontra no procfs. Ele tem algumas informações interessantes sobre o processo, mas é importante vc sempre ler o manual do kernel, pq as informações não são muito interativas. Mas ali vc encontra informações como o PID, comando de execução, o estado, PPID, Pgrp que é o grupo de processos, Session ID que define a sessao que o processo pertence, Tty_nr, flags do bitmasks, minflt e varias outras coisas.

Outro arquivo interessante do procfs associado sempre ao processo é o "io", ou /proc/PID/io, que informa quanto o processo esta fazendo de I/O.

  • rchar, ou quantidade total de bytes lidos e escritos pelo processo. Mesmo que as informações tenham sido descartadas.

  • wchar, que é a quantidade total de bytes escritos "com sucesso" pelo processo.

  • syscw, que é o numero de chamadas do sistema que o processo usou para escrever dados no sistema de arquivo.

  • read_bytes, quantidade total de bytes lidos pelo processo no disco.

  • write_bytes, que é a quantidade total de bytes gravados pelo processo no disco. E quando falo disco eu falo do filesystem.

Muitos dos arquivos que estou mostrando servem para debugar e fazer troubleshoot para resolução de muitos problemas e um deles que serve muito para debugar informações sobre processos é o "environ", que vai informar todas as variáveis que esse processo em execução esta utilizando. Por exemplo, vou verificar com o comando pidof o pid do crond. Após isso, vou verificar o arquivo environ.

[root@poder ~]# pidof cron
1670
[root@poder ~]# cat /proc/1670/environ
LANG=en_US.UTF-8PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/binINVOCATION_ID=c6d4f05193a740ecb12c773a10e96e55JOURNAL_STREAM=9:32739CRONDARGS=n

Com essa saída eu consigo entender que um simples crond, usado para agendar tarefas no sistema, esta sendo gerenciado pelo systemd. Eu percebi isso por causa do seu INVOCATION_ID que contém o seu identificador único para cada execução do systemd. Também observado que ele possui a sua própria variável, extraída do seu arquivo de configuração como PATH e CRONDARGS. Outra coisa interessante é que vejo que este processo esta sendo monitorado pelo systemd-journald do systemd. Mas pq eu vejo isso? Percebam o JOURNAL_STREAM? Então, ele é o fluxo de registro, ou quase uma "fila" para o systemd-journald.

Outro arquivo muito importante do procfs é o "uid_map", que indica o valor do mapeamento "original"do namespace do processo. Isso é muito útil para entender o quanto o processo pode ser isolado pelo kernel.

Interessante né? podemos explorar bastante coisa do mundo de processos no UNIX e Linux. É o poder ;)

aprigiosimoes@gmail.com