Gerenciando processos no Linux
Tags: braziliandevs, linux, resume
Published: 2021-11-14 22:01:57

## Introdução
Provavelmente você já deve ter ouvido sobre "processos" enquanto estava mexendo em seu computador. A maioria de nós talvez só nos damos conta da existência deles em "momentos ruins", por exemplo, quando alguma aplicação está travada e temos que "finalizar o processo dela". Contudo, fora o conhecimento em saber como finalizar o "bendito" para você continuar exercendo suas atividades, algo importantíssimo também é entender qual é a real importância de um processo.

## O básico sobre Processos

Quando estamos trabalhando em um ambiente multiprogramado/multitarefa, o Sistema Operacional (SO) é responsável por gerenciar diversos programas executados "concorrentemente", controlando o compartilhamento dos recursos para cada um deles. Para que isso seja possível, todo programa executado deve sempre estar associado a um **processo**. Processo por sua vez, pode ser entendido como um programa em execução. Um programa de computador é uma "coleção passiva de instruções", enquanto que um processo é a "execução real" dessas instruções.

Cada CPU (*Central Processing Unit*, ou Unidade Central de Processamento) executa uma única "tarefa" por vez. Contudo, quando estamos lidando com um ambiente multiprogramado/multitarefa, há mecanismos que permitem que vários processos possam compartilhar CPUs e outros recursos da máquina, "comutando" entre tarefas que estão sendo executadas, sem ter que esperar necessariamente que cada uma delas de fato finalize (Essa "comutação", na qual me referi, irá variar de SO para SO se você quiser saber mais sobre isso, comece pesquisando por "Troca de Contexto" e "Compartilhamento de Tempo").

Imagine uma situação que temos duas tarefas: Uma mais lenta e outra mais rápida. Em um sistema com multiprogramação, as duas tarefas serão executadas "simultaneamente". Logo, a que é mais rápida estará disponível antes. Em sistemas sem multiprogramação, pode acontecer que da tarefa mais rápida ter que esperar a mais lenta terminar (vai depender do momento em que ela for "iniciada").

É válido ressaltar, que em sistemas multiprogramados, um processo pode passar por vários estados, que vão desde a sua criação até o seu término. A princípio, pode-se dizer que existe a ideia de sete estados de processos, são eles (não definitivamente nessa ordem ou com essas terminologias): Não Submetido, Criando, Pronto, Executando, Aguardando Evento Externo, Esperando e Encerrando. O SO reúne essas e outras informações do processo em uma estrutura de dados chamada PCB (*Process Control Blocks*).

Basicamente, o PCB permite ao SO localizar toda a informação do processo. O conjunto de PCBs forma o que chamamos de "tabelas de processos". É interessante ressaltar também que cada processo possui seu próprio PCB. A seguir temos algumas informações que geralmente estão contidas em um PCB:

- PID (Identificador do processo);
- Registradores da CPU;
- O espaço de endereçamento do processo;
- A prioridade do processo;
- O estado do processo;
- Informações sobre o escalonamento de processo;
- Informações de entrada/saída;
- O ponteiro para o próximo PCB;

Pronto! Acho que agora nós já começamos a entender melhor o conceito de processo, alguns de seus mecanismos, e também, como ele é gerenciado pelo SO. Vamos colocar um pouquinho de "mão na massa" e aprender alguns comandos interessantes para estarmos trabalhando com processos no Linux.

## Visualização/Gerenciamento de Processos - Linux

Para melhorar um pouco mais os nossos estudos, estarei separando uma série de comandos interessantes para serem utilizados em sistemas baseados no **Linux** no que diz respeito à visualização e gerenciamento de processos. Provavelmente eu não vou conseguir cobrir tudo que cada um desses comandos é capaz de fazer, desta maneira, sugiro que você reserve um tempinho posteriormente para ler mais sobre eles utilizando o comando `man + <nome_do_comando>`.

### Comandos ps e pgrep

Provavelmente esses são os comandos mais simples que você pode encontrar, em sistemas baseados no Linux, no que diz respeito a visualização de processos. Mesmo simples, não os subestimem, pois são extremamente poderosos se usados da maneira correta. Vamos iniciar com o comando `ps`.

O comando `ps` exibe um relatório simples contendo informações dos processos que estão ativos. É válido ressaltar, que ele funciona como uma espécie de "snapshot", ou seja, só exibe informações dos processos no momento exato em que o comando foi executado. Ele possui várias flags para melhorar sua visualização, abaixo estarei listando algumas para você testar em sua máquina:

- `ps` (Comando em seu estado mais básico, exibe informações básicas sobre o seu shell atual e sobre o próprio comando ps);
- `ps -eF` (Para listar todos os processos do sistema no formato padrão);
- `ps -eFH` (Lista todos os processos do sistema no formato padrão, contudo, exibindo uma espécie de "árvore", associando o "processo filho" ao "processo pai");
- `ps -C chrome -o pid=` (Exibe apenas os processos associados a um programa, nesse caso, exibe todos os processos associados ao "chrome");
- `ps -q 42 -o comm=` (Exibe o nome do comando associado ao processo em questão, nesse caso, estamos querendo descobrir qual o comando relacionado ao processo "42");
- `ps -eo pid,ppid,stat,comm` (Caso você queira especificar as colunas que serão exibidas, você pode usar a flag "-o" juntamente com os nomes das colunas desejados. Nesse exemplo, estamos solicitando uma lista contendo o PID, o PPID, o estado atual do processo e o comando que o originou - Para visualizar a lista completa de colunas disponível, utilize o comando `man ps` e vá até a sessão ***STANDARD FORMAT SPECIFIERS***);

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8n4tgmu40ahvjm9ni1fm.jpeg)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/btals9abx90tdwqcdcma.jpeg)

O comando `prgrep`, por sua vez, é um pouco mais simples. Ele basicamente irá listar os processos associados a um nome, e caso você desejar, com base em alguns filtros específicos. Abaixo, temos alguns exemplos de como utilizar o `pgreg`:

- `pgrep chrome` (Lista os processos associados a um nome, nesse caso, estamos fazendo a listagem dos processos associados ao nome "chrome")
- `pgrep -u root,mdcg` (Lista os processos pertencentes a um determinado usuário, no exemplo em questão, estamos fazendo a busca para os usuários "root" e "mdcg")
- `pgrep -o chrome` (Exibe apenas o processo mais antigo associado a um nome, nesse caso, estamos verificando o do chrome)
- `pgrep -d, chrome` (Por padrão, o comando pgrep irá exibir cada processo encontrado em uma nova linha. Utilizando a flag "-d", nós podemos especificar um novo delimitador. No exemplo em questão, estamos listando os processos associados ao chrome separados por vírgula)
- `pgrep -x chrome` (O `pgrep` funciona fazendo uma busca com base no nome especificado, porém, talvez nós gostaríamos de fazer uma busca exata com base no nome informado. Para isso, nós podemos utilizar a flag "-x". No exemplo em questão, estamos fazendo uma busca dos processos que estejam associados exatamente ao nome/processo "chrome")
- `ps -fp $(pgrep -d, -x chrome)` (Aqui estamos fazendo um uso do ps associado ao pgrep. Basicamente, estamos pegando o stdout do comando pgrep -d, -x chrome, e enviando para o stdin do comando ps -fp. Desta maneira, nós teremos um relatório mais detalhado dos processos relacionados ao "chrome")

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qxttsvz7hr574jvygaew.jpeg)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3gm08t939mb23uwhztok.jpeg)

Novamente, não deixe de utilizar o comando `man` para aprender ainda mais em como utilizar os comandos `ps` e `pgrep`.

### Comando top

Um comando muito interessante para você estar acompanhando os processos no Linux em tempo real é o comando `top`. Ele possui diversas informações extremamente pertinentes para que você possa ter um maior controle do que está acontecendo em seu SO. Você pode acompanhar o consumo de CPU e memória, ter relatórios com o número tasks que estão ativas, além das informações que já tínhamos utilizando o comando `ps`, contudo, num formato muito mais "amigável".

É interessante falar também que o `top` permite diversas personalizações. Ao todo, a partir de um processo, você pode gerar até *58 colunas de informações* (Utilizando o comando `man`, vá para a sessão ***3 - FIELDS / Columns***).

O `top` também é interativo, ou seja, durante a sua execução, você pode a todo momento estar modificando a forma em que os dados estão dispostos, a fim de ter uma visibilidade e um controle maior (Para ter acesso a lista de todas as interações permitidas pelo `top`, utilize o comando `man` e vá para a sessão ***4 - INTERACTIVE Commands***).

Abaixo estarei listando alguns comandos que eu geralmente uso quando estou trabalhando com o top, contudo, a minha lista não chega nem na metade de todas as opções que a ferramenta dispõe:

- **Setas direcionais** (Mover a tela para visualizar melhor a informação);
- **Enter/Espaço** (Atualização rápida (Refresh) - Você também pode utilizar a opção d / s para definir o intervalo de atualização automático, mas não é muito recomendado);
- **m** (Melhora a visualização do uso de memória);
- **t** (Melhora a visualização do uso de CPU, caso você queira visualizar o uso em cada um dos núcleos separadamente, basta digitar **1**);
- **k** (Finalizar um processo);
- **Z** (Opção para mudar de cor. Você pode estar utilizando a tecla "a" para estar escolhendo também qual elemento da tabela que você deseja modificar a cor);
- **J** (Altera entre o alinhamento à direita/esquerda para colunas numéricas);
- **j** (Altera entre o alinhamento à direita/esquerda para colunas de caracteres);
- **u** (Visualizar processos relacionados a um determinado usuário (blank para visualizar todos);
- **c** (Exibe/Omite o "comando" originador do processo);
- **n** (Quantidade de processos a serem exibidos na tabela);
- **x** (Destaca a coluna que está selecionada. Esse comando será bastante útil quando estivermos trabalhando com a critérios de ordenação do top);
- < ou > (Move entre as colunas que você deseja ordenar);
- **R** (Ordem reversa da coluna selecionada);
- **M** (Atalho para selecionar a coluna %MEM);
- **N** (Atalho para selecionar a coluna PID);
- **P** (Atalho para selecionar a coluna %CPU);
- **T** (Atalho para selecionar a coluna TIME+);
- **q** (Sair do top)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kpo3cnqeed5i2jkrpy1p.jpeg)

Existem muitos outros comandos disponíveis além desses que eu citei, novamente, sugiro que para você ter um maior aprendizado, utilize o comando `man`.

Outros dois programas interessantes que você pode estar dando uma pesquisada são o `htop` e o `atop`. Eles são bastante similares ao comando `top`, contudo, por não serem "nativos" não abordei aqui nessa postagem.

### Comando kill e pkill

Uma vez que você agora consegue visualizar e identificar os processos, pode ser agora que você deseje "forçar a parada da execução de algum", seja porque ele está sendo problemático para o SO, ou apenas por pura vontade sua. Gostamos de nos referenciar a esse tipo de ação como "matar um processo" (por isso o nome dos comandos "kill"). Iniciaremos nossos exemplos com o comando `kill`.

Diferentemente do que se pensa, o comando `kill` não é feito diretamente para "matar" um processo. Ele na verdade é um comando para "enviar sinais" (*signals*) para um processo. Para ficar mais fácil o entendimento do que é um "signal", veja como uma forma de comunicação entre os processos. Existem vários signals disponíveis, mas ao meu ver, os mais conhecidos são o **SIGINT** (Interrupção, ctrl + c), **SIGSTOP** (Parada temporária, ctrl + z), **SIGTERM** (Término) e **SIGKILL** (Matar).

Por padrão, o comando `kill` irá enviar o signal SIGTERM para um processo, indicando que ele deve "terminar" sua execução. Porém, em alguns cenários, o SIGTERM não é o suficiente para fazer com que um processo "pare a sua execução", para que isso de fato aconteça, precisamos enviar um SIGKILL. Abaixo temos alguns exemplos de como executar o comando `kill`:

- `kill -l` (Exibe todos os signals disponíveis. A partir dessa lista, você pode escolher entre três formas de enviar um signal: Pelo número; pelo nome completo do signal, nesse caso com o prefixo "SIG"; ou se desejar, você pode também omitir o "SIG").

Todos os comandos abaixo são equivalentes, basicamente eles estão enviando o signal SIGKILL para o processo associado ao PID 42:

- `kill -SIGKILL 42`
- `kill -KILL 42`
- `kill -s SIGKILL 42`
- `kill -s KILL 42`
- `kill -s 9 42`

Lembra do comando `pgrep`? Temo uma versão muito parecida com ela (inclusive, de mesma autoria), chama `pkill`. Para utilizar o pkill, basta que você informe um nome, e caso sejam encontrados processos relacionados a ele, todos receberam um determinado signal. Por exemplo:

- `pkill chrome` (Envia um signal SIGTERM para todos os processos associados ao "chrome");
- `pkill -KILL chrome` (Envia um signal SIGKILL para todos os processos associados ao "chrome");

Fazendo uma menção honrosa rápida, posso indicar também o comando `killall` que funciona de maneira idêntica ao `pkill`.

### Comando nice e renice

Como dito anteriormente, sistemas multiprogramados/multitarefas estão a todo o tempo gerenciando o tempo de CPU de cada processo, comutando entre tarefas que estão sendo executadas. Contudo, por trás dos algoritmos responsáveis por essas comutações, estão definidos também algumas "priorizações" para utilização de tempo de CPU. Caso você deseje especificar uma alta/baixa priorização para um determinado processo, você deve alterar seu ***Nice Value*** (*niceness*). Para isso, utilizamos os comandos `nice` e `renice`.

Um detalhe importante antes de iniciarmos de fato a explicação dos comandos nice e renice, é que o Linux trabalha com números de prioridade que vão de **-20** a **+20**, porém, contraintuitivamente, a regra é inversamente proporcional: quanto menor o número especificado, maior sua prioridade. Em outras palavras, se você quiser que um processo tenha alta prioridade, coloque um valor baixo, como por exemplo -10.

A diferença primordial entre o `nice` e o `renice`, é a forma em que eles são "chamados". Se você precisa que um determinado processo inicialize já com uma prioridade alta/baixa, você deve utilizar o comando `nice`. Porém, se um processo já está em execução e você deseja alterar sua prioridade, utilizamos o comando `renice`. Simples assim. Abaixo temos alguns exemplos da utilização do `nice` e do `renice`:

- `nice -n 10 /opt/google/chrome/chrome` (Atribui um certo valor de prioridade durante a inicialização de um determinado processo, no exemplo em questão, estamos inicializando o chrome com um valor "niceness" de 10);
- `renice -n 10 -p 42` (Atribui um certo valor de prioridade a um processo já em execução, nesse caso, estamos modificando o valor "niceness" do processo 42 para 10);
- `renice 10 42` (Comando idêntico ao anterior, contudo, suprimindo as flags "-n" e "-p", que são tidas como "padrão" durante a execução do comando);
- `renice 10 -u mdcg` (Altera a prioridade de todos os processos associados ao usuário especificado, no exemplo em questão, estamos alterando o valor "niceness" de todos os processos associados ao usuário "mdcg" para 10);
- `renice 10 -p $(pgrep chrome)` (Você pode utilizar também associações de comandos dessa forma, no exemplo em questão, capturando o stdout do comando `pgrep chrome` e inserindo como stdin no comando `renice 10 -p`, dessa forma, todos os comandos associados ao chrome terão seus respectivos valores "niceness" alterados para 10);

## Conclusão

Enfim chegamos ao final de mais uma postagem. Eu sei, é muita informação, mas não se desespere! Alguns desses conceitos virão com a prática e com o passar do tempo e lembre-se que você pode sempre estar consultando a documentação de cada um desses comandos utilizando o comando `man`.

Muito obrigado pela leitura e até a próxima!

## Bibliografia

- [O que são processos de um sistema operacional e por que é importante saber](https://www.tecmundo.com.br/memoria/3197-o-que-sao-processos-de-um-sistema-operacional-e-por-que-e-importante-saber.htm)
- [5-Processo - Prof Fernando De Siqueira - Sistemas Operacionais](https://sites.google.com/site/proffernandosiqueiraso/aulas/5-processo)
- [Processo (informática)](https://pt.wikipedia.org/wiki/Processo_(inform%C3%A1tica))
- [Bloco de controle de processo](https://pt.wikipedia.org/wiki/Bloco_de_controle_de_processo)
- [Unix / Linux - Processes Management](https://www.tutorialspoint.com/unix/unix-processes.htm)
- [30 Useful 'ps Command' Examples for Linux Process Monitoring](https://www.tecmint.com/ps-command-examples-for-linux-process-monitoring/)
- [Linux/Unix Process Management: ps, kill, top, df, free, nice Commands](https://www.guru99.com/managing-processes-in-linux.html)
- [Show All Running Processes in Linux using ps/htop commands - nixCraft](https://www.cyberciti.biz/faq/show-all-running-processes-in-linux/)
- [8 Linux commands for effective process management](https://opensource.com/article/18/9/linux-commands-process-management)
- [How to check running process in Ubuntu Linux using command line - nixCraft](https://www.cyberciti.biz/faq/how-to-check-running-process-in-ubuntu-linux-using-command-line/)
- [Linux / UNIX: Kill Command Examples - nixCraft](https://www.cyberciti.biz/faq/unix-kill-command-examples/)
- [Alterando a prioridade de processos](https://www.dicas-l.com.br/arquivo/alterando_a_prioridade_de_processos.php)
- [Nice and Renice Command in Linux with Examples - GeeksforGeeks](https://www.geeksforgeeks.org/nice-and-renice-command-in-linux-with-examples/)
- [Guia Linux](https://guialinux.uniriotec.br/renice/)
- [Processos - Conceitos Básicos](http://www.inf.ufes.br/~zegonc/material/Sistemas_Operacionais/Processos%20(1)%20-%20Conceitos%20basicos.pdf)