![]() |
![]() |
![]() |
![]() |
![]() |
Gerenciando processos |
Um processo é, simplesmente falando, um programa sendo executado. Mais
específicamente, do ponto de vista do sistema operacional, é uma
coleção de instruções (programa) mais os dados
necessários à sua execução. Armazenados juntamente
com o processo estão o seu contexto, ou seja, o contador de
instruções [17], e o conjunto de
todos os registradores da CPU.
Processos são entidades independentes, cada um com suas
permissões de acesso, e têm atribuidos propriedades como o
id do usuário que o criou (UID) e do
grupo (GID). Grande parte de sua execução se
processa em user-mode, quando o processador não admite a
execucão de instruções privilegiadas, mas em certos
instantes (durante uma chamada de sistema), ele executa em
kernel-mode para conseguir o acesso a partes do hardware que de outra
forma seriam inacessíveis. Cada processo é identificado pelo
seu process id (PID), que é simplesmente um
número inteiro.
É responsabilidade do sistema operacional gerenciar os processos do sistema, de forma a maximizar a utilização da CPU (que usualmente é só uma), de forma que, se um processo tenta ler ou escrever em um disco, por exemplo, este processo ficará em estado waiting (suspenso) até que a operação de entrada/saida seja completada. Nesse ínterim, outro processo será habilitado a rodar, desperdiçándo assim o mínimo do tempo da CPU, memória e demais periféricos. O Linux suporta inclusive um procedimento de "escrita retardada", quando escrevemos em algum arquivo. No momento da escrita, o buffer que contém estes dados é simplesmente marcado como "sujo" (dirty), e o sistema operacional escolhe o instante mais apropriado para descarregar esse buffer no disco físico. Isso explica a necessidade que temos de executar um procedimento de parada (shutdown) antes de desligar a máquina, para evitar que fiquem dados a serem descarregados (escritos) no disco.
O diretório /proc
contém, como vimos anteriormente,
um subdiretório com o nome do PID de cada processo. Os pseudo-arquivos
cmdline
, environ
e status
, têm
informações detalhadas sobre esse processo. Outra forma é
obter um resumo sobre o processo via o comando ps
. Outro comando
que permite controlar diretamente processos é o top
,
útil quando queremos deixar um terminal como console permanente do
sistema. O top
mostra constantemente os processos em ordem
decrescente de utilização de CPU, permitindo o operador enviar
sinais (signals) para interromper um processo que esteja tomando muitos
recursos da CPU, ou mesmo modificar a prioridade de execucão de um
determinado processo. Ainda outros comandos, o nice
, e o
renice
, nos dão controle individual sobre a prioridade de
um processo. Um processo tem prioridades variando entre -20 (maior prioridade)
até 19 (menor prioridade). o comando nice
roda um programa
com uma prioridade aumentada em 10, enquanto que o renice
permite-nos ajustar essa prioridade, de um processo já sendo executado,
adicionando ou subtraindo o valor dado. Somente o superusuário pode
executar tarefas com ajustes de prioridade negativos.
atributos
Um processo tem vários atributos que controlam sua
execução. |
![]() |
À medida que vai sendo executado, um processo passa por vários
estados. Logo que é iniciado ele é colocado no estado
ready, isto é, pronto para executar. O escalador
(scheduler), uma das partes do kernel, decide, de acordo com
a prioridade e a ordem das suas filas, quando dar a CPU para esse processo,
quando ele passa ao estado running. Se este processo fica
muito tempo, acima de um determinado time slot, com a CPU, ele
é novamente colocado na fila ready e fica aguardando
uma nova escalação. Quando o processo tenta efetuar alguma
operação de entrada e saida, ele pode ser bloqueado e passa ao
estado waiting, até que a operação de
I/O (entrada/saida) seja completada. Se o processo está sendo, por
exemplo, monitorado ou controlado por outro programa (digamos, um depurador
como o gdb
), ele poderá ser enviado ao estado
stopped, até que o programa que o controla retorne-o
ao estado ready novamente. No final da
execução, o processo pode ser morto (por exemplo com o comando
kill
). Processos que terminam sem que o seu pai (parent)
seja informado, podem ficar num estado zombie (zumbi), que na
realidade nada mais é que um processo morto, mas
órfão.
Existem vários tipos de processos no Linux:
Processos interativos são iniciados a partir de uma sessão de terminal e por ele controlados. Quando executamo
s um comando do shell, entrando simplesmente o nome do programa e
<return>
(tecla enter
no teclado do PC), estamos
rodando um processo em foreground. Um programa em
foreground recebe diretamente sua entrada (stdin) do
terminal que o controla, e por outro lado, toda sua saida (stdout e
stderr) vai para esse mesmo terminal. Digitando Ctrl-Z, suspendemos
esse processo, e recebemos (do shell) a mensagem:
Stopped
(talvez com mais alguns caracteres dizendo o número do job e a
linha de comando). A maioria dos shells têm comandos para controle de
jobs, para mudar o estado de um processo parado para
background, listar os processos em
background, retornar um processo do back
para o foreground, de modo que o possamos controlar novamente
com o terminal. No
bash
o comando jobs
mostra os
jobs correntes, o bg
restarta um processo
suspenso em background e o comando fg
o restarta
em foreground.
Processos em batch são controlados usualmente pelo cron
,
juntamente com o programa at
ou batch
(na realidade
um link para o at
). Introduzindo no shell: at 18:30
e em seguida uma linha com o comando desejado, teremos essa
execução programada para a hora dada (no caso 18:30). O comando
atq
lista todas as tarefas pendentes. A saida do comando at
será enviado por mail para o usuário, quando a
execução estiver completa.
Daemons ou processos servidores, mais frequentementes são iniciados na partida do sistema, rodando continuamente enquanto o sistema está no ar, e esperando em background até que algum outro processo solicite o seu serviço. É o caso, por exemplo, do sendmail, um programa para redirigir e transportar mensagem de mail através do sistema ou para outros sistemas interligados via rede.