# 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:

```plaintext
# 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:

```plaintext
[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:

```plaintext
[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/&lt;PID&gt;** 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](https://media.licdn.com/dms/image/D4D12AQF0LU3W4y2lHw/article-inline_image-shrink_1500_2232/0/1680458295540?e=1686182400&v=beta&t=xCGkaFpr-qwxa6xtaHqB1M-yBKfwOO7Lv_r6-tGFgVQ align="left")

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](https://docs.kernel.org/filesystems/proc.html) 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.

```plaintext
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.........................

```plaintext
# 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.

```plaintext
[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](mailto:aprigiosimoes@gmail.com)
