Escolar Documentos
Profissional Documentos
Cultura Documentos
Gerência de Processos
Nos primeiros sistemas de computação somente um programa podia ser executado por vez, com
acesso e controle pleno do sistema e seus recursos. A multiprogramação exige maior controle dos
programas em execução. Resultou disto o conceito de processo, que é a unidade de trabalho de
sistemas operacionais modernos de tempo compartilhado. Um sistema é uma coleção de processos: os
de sistema operacional e os de usuário. Programas devem ser executados seqüencialmente.
Conceito de Processo
Processo (Job, Tarefa) é o ambiente no qual um programa é executado. É formado por três partes:
contexto de hardware, contexto de software e espaço de endereçamento. O contexto de hardware
armazena o conteúdo dos registradores da UCP e dos registradores de uso específico, como o
contador de programa (PC) – endereço da próxima instrução , ponteiro de pilha (SP) e registrador de
status (SR). Uma das tarefas cruciais da mudança de contexto é salvar o contexto de hardware do
processo preemptado e carregar os registradores com o contexto de hardware do processo selecionado
para execução. No contexto de software são especificadas características e limites de recursos que
podem ser alocados ao processo. Ele contém três grupos de informações: identificação (Process
Identification, User Identification, etc), quotas (número máximo de arquivos abertos, tamanho
máximo da memória principal e secundária, número máximo de operações pendentes de E/S,
tamanho máximo de buffer, número máximo de subprocessos e threads) e privilégios (direitos). O
espaço de endereçamento é a área de memória pertencente ao processo para instruções e dados.
nom e
P ID r e g i s tr a d o r e s
g e r a is
o w n e r (U I D )
p r io r id a d e d e
r e g i s tr a d o r P C
e xe cu çã o
d a ta / h o r a
d e cr ia çã o C o n te x t o d e C o n te x to d e
S o f tw a r e H a rd w a re
te m p o d e r e g i s tr a d o r S P
p ro ce ssa d o r
q u o ta s
Pro g ra m a r e g i s tr a d o r
p r iv ilé g io s d e s ta tu s
E sp a ço d e
E n d e r e ç a m e n to
e n d e r e ço s d e m e m ó r ia
p r in c ip a l a lo ca d o s
Um programa é uma entidade passiva, enquanto um processo é uma entidade ativa.
Dois processos podem ser associados ao mesmo programa. Por exemplo: vários usuários (ou mesmo
2
um) podem executar cópias diferentes do mesmo programa.
Estado do Processo
Conforme um processo é executado, ele muda de estado
Estados comuns
Novo: O processo está sendo criado
Executando: As instruções estão sendo executadas
Esperando: O processo está esperando que ocorra algum evento
Pronto: O processo está esperando para ser atribuído a um processador
Terminado: O processo terminou sua execução
Este é um esquema básico e é implementado de formas mais detalhadas em cada caso.
Apenas um processo pode estar em execução em cada processador a cada instante.
Bloco de Controle de Processo
Também chamado Bloco de Controle de Tarefa ou Process Control Block (PCB)
3
Informações associadas a cada processo : Estado do processo, Contador de programa, Registradores
da CPU , Informação de escalonamento de CPU, Informação de gerenciamento de memória
(registradores de base e limite, etc), Informação contábil (quantidade de tempo de UCP utilizado,
números de subprocessos, etc), Informação de status de E/S.
O modelo clássico de processo considera implicitamente que exista um único fluxo de execução em
cada processo. Nesta caso um usuário não poderia, por exemplo, utilizar abas em um navegador.
Processos podem implementar múltiplos fluxos de execução, conhecidos como threads.
Escalonamento de processos
À medida que os processos são criados eles são colocados em uma fila de processos, com todos os
processos do sistema. Os processos prontos são mantidos na fila de processos prontos (Ready queue),
geralmente uma lista encadeada. Um cabeçalho mantém ponteiros para o primeiro e o último
elemento e cada elemento tem um ponteiro para o seguinte. Existem as filas de dispositivo.
Uma representação comum é o do diagrama de filas
4
Processos Foreground e Background
Um processo sempre está associado a pelo menos dois canais de comunicação, o de entrada e o de
saída. Um processo foreground é aquele que permite a comunicação direta do usuário com o processo
durante o processamento. Um processo background é o que não existe a comunicação com o usuário
durante o processo.
É possível associar o canal de saída de um processo ao canal de entrada de outro processo, criando um
pipe.
Escalonadores
O ato de selecionar processos para serem colocados nas diferentes filas é executado pelo escalonador
(scheduler) adequado.
Em um sistema em lote o escalonador de longo prazo ou escalonador de jobs seleciona processos do
spool e carregaos na memória. O escalonador de curto prazo ou escalonador de UCP seleciona entre
os processos prontos e aloca um deles para a UCP. Um escalonador de curto prazo é executado com
freqüência, em geral pelo menos uma vez a cada 100 milissegundos. Se ele gastar 10 milissegundos a
cada 100 milissegundos, 9% do tempo da UCP será desperdiçado com escalonamento. O escalonador
de longo prazo pode ficar minutos sem ser executado.
O escalonador de longo prazo controla o grau de multiprogramação (número de processos em
memória). Um processo limitado por E/S (I/Obound) passa mais tempo em E/S do que utilizando a
UCP. Um processo limitado por UCP (CPUbound) gera pedidos de E/S com pouca freqüência. Se
todos os processos carregados forem limitados por E/S, a Ready Queue estará geralmente vazia. Se
todos os processos carregados forem limitados por UCP, a fila dos dispositivos estará geralmente
vazia. O escalonador de longo prazo precisa seleção rigorosa para balancear estas duas categorias. Em
alguns sistemas, como os de tempo compartilhado, o escalonador de longo prazo pode estar ausente
(como no Unix) ou ser mínimo. O equilíbrio destes sistemas depende de uma limitação física (número
de terminais) ou da natureza de autoajuste dos usuários humanos, que simplesmente desistem de
utilizar o sistema e se o desempenho atingir níveis abaixo do aceitável.
Alguns sistemas introduzem o escalonador de médio prazo, pois às vezes é vantajoso reduzir
temporariamente o grau de multiprogramação, reduzindo a disputa por UCP e recursos. Este esquema
é chamado de swapping (troca). O swapping é realizado para melhorar a combinação de processos ou
para liberar um recurso, como memória.
5
Troca de Contexto
A tarefa de alternar a UCP entre processos é a troca de contexto ou mudança de contexto.
O tempo de troca de contexto é overhead (custo adicional), pois o sistema não realiza qualquer
trabalho útil durante a troca. Este tempo depende do hardware (velocidade da memória, número de
registradores e instruções especiais que possam realizar a carga e armazenamento de registradores de
forma mais eficiente). Costuma levar entre 1 e mil microssegundos. Alguns processadores Sun
UltraSPARC fornecem distintos conjuntos de registradores e basta alterar um ponteiro para o conjunto
atual.
Criação de Processo
Os processos pai criam processos filhos, que, por sua vez, criam outros processos, formando uma
árvore de processos. Esta criação é feita por chamadas de sistema.
Um processo filho pode receber recursos diretamente do sistema operacional, obter um subconjunto
dos recursos do processo pai ou mesmo compartilhar todos os recursos do processo pai
Dados de inicialização podem ser passados do processo pai para o processo filho.
Ao criar um processo filho o processo pai pode continuar a executar concorrentemente com o
processo filho ou esperar até que alguns ou todos processos filhos tenham terminado.
O espaço de endereçamento do processo filho pode ser uma duplicata do processo pai ou ter um
programa carregado para ele.
No Unix um novo processo é criado por uma chamada de sistema fork. O novo processo recebe uma
cópia do espaço de endereçamento do processo pai. Ambos processos continuam a execução após o
fork. O processo filho recebe um retorno zero do fork e o processo pai recebe o PID do processo filho.
Ao receber um retorno zero (o que acontece com o processo filho), é executada a chamada de sistema
execlp que carrega um novo programa na memória, destruindo a imagem na memória que contém a
chamada de sistema execlp. O processo pai, se não tiver nada para fazer, pode emitir uma chamada de
6
sistema wait para sair da fila de processos prontos até o término do processo filho.
Programa em C
criando um processo separado
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int pid;
/* cria outro processo */
pid = fork();
if (pid < 0) { /* ocorreu erro na execução do Fork */
fprintf(stderr, “Falha no Fork ");
exit(1);
}
else if (pid == 0) { /* processo filho */
execlp("/bin/ls","ls",NULL);
exit(1);
}
else { /* processo pai */
wait(NULL); /* pai espera o término do filho */
printf(“Filho terminou ");
exit(0);
}
}
No VMS da DEC, o processo cria um processo filho e carrega nele um novo programa. O Windows
NT permite as duas abordagens.
Término do processo
Um programa termina quando sua instrução final é executada, pedindo para ser excluído com a
chamada de sistema exit. Ele pode retornar dados para o processo pai, que os receberá na chamada
wait. Os recursos são desalocados.
Um processo pode causar o término de outros por uma chamada de sistema como abort ou kill.
Geralmente apenas o processo pai pode efetuar uma chamada destas em relação a um processo filho.
Um processo pai pode fazer isso em decorrência de um processo filho exceder no uso de recursos,
pela tarefa deste não ser mais exigida ou por estar terminando quando o sistema operacional não
permite que um processo filho continue se seu processo pai terminar (término em cascata).
No Unix, se um processo terminar sem conseguir “matar” os processos filhos, estes receberão o
processo init como seu novo pai.
7
Processos Cooperantes ou Cooperativos
Processos concorrentes podem ser independentes ou cooperativos
Um processo independente não pode afetar ou ser afetado pela execução de outro processo. Um
processo cooperante pode afetar ou ser afetado pela execução de outro processo.
Vantagens da cooperação de processos: Compartilhamento de informações, agilidade na computação
(subtarefas), modularidade e conveniência.
O Problema do produtorconsumidor é paradigma para os processos cooperativos. Um processo
produtor gera informações que são consumidas por um processo consumidor. Exemplos podem ser um
programa de impressão e o driver da impressora ou um compilador e o montador.
É preciso um buffer compartilhado entre os dois processos. O consumidor não pode consumir um
item que não tenha sido completamente produzido.
Há duas opções para o buffer. O buffer ilimitado (unboundedbuffer) não coloca qualquer limite
prático no tamanho do buffer, permitindo que o produtor sempre possa produzir novos itens. O buffer
limitado (boundedbuffer) considera que existe um tamanho de buffer fixo e o produtor terá de esperar
se o buffer estiver cheio.
O buffer pode ser fornecido pelo sistema operacional pelo uso de recurso de comunicação entre
processos (IPC, InterProcess Communication) ou codificado pelo programador.
Comunicação Entre Processos
O IPC é particularmente útil em ambientes distribuídos, como em um programa de chat ou mensagens
instantâneas. O IPC é implementado por um sistema de troca de mensagens. O recurso de IPC oferece
pelo menos duas operações:
send(mensagem) – tamanho de mensagem fixo ou variável – e receive(mensagem). Mensagens de
tamanho fixo são fáceis de implementar e dificultam a programação. O inverso ocorre com as
mensagens de tamanho variável.
Se os processos P e Q desejam se comunicar, eles precisam estabelecer um enlace de comunicação
entre eles e trocar mensagens através de send/receive.
A implementação do enlace de comunicação precisa de um lado físico (memória compartilhada,
barramento do hardware) e lógico (propriedades lógicas).
O arranjo lógico do enlace utiliza diversos métodos:
● Comunicação direta e indireta
● Comunicação simétrica e assimétrica
● Buffering automático ou explícito
● Envio por cópia ou referência
● Mensagens de tamanho fixo ou variável.
Na comunicação direta um processo envia uma mensagem diretamente para o outro que precisa ser
conhecido. Estabelecese um canal exclusivo e único a estes processos
Comunicação direta com simetria de endereços:
send(P, mensagem)
receive(Q, mensagem)
8
Comunicação direta com assimetria de endereços:
send(P, mensagem)
receive(id, mensagem)
Na comunicação indireta as mensagens são enviadas e recebidas por caixas de correio ou portas. Os
dois processos precisam de ao menos uma caixa de correio em comum, que pode estar associada a
outros processos.
send(A,mensagem) – mensagem enviada para o caixa de correio A
receive(A,mensagem)
É importante avaliar o que aconteceria se mais de um processo tentar ler uma mesma caixa de correio.
O esquema pode escolher entre permitir a associação de uma caixa a dois processos no máximo;
permitir que no máximo um processo execute um receive ou identificar o destinatário.
As caixas de correio podem ser propriedade de um processo ou do sistema operacional. Se pertencer a
um processo é possível fazer a distinção entre o proprietário (que recebe mensagens nesta caixa) e os
usuários (que enviam mensagens para a caixa). Se pertencer ao sistema operacional, este deve
implementar métodos para criação, manipulação e exclusão de caixas. O processo que criar a caixa é
o proprietário, embora vários destinatários possam utilizala.
Sincronização
A troca de mensagens pode ser bloqueante (síncrona) ou nãobloqueante (assíncrona). Temos tanto
envio bloqueante e envio nãobloqueante como recepção bloqueante e recepção nãobloqueante. Se
ambos forem bloqueantes, configurase um rendezvous (encontro, em francês).
Buffering
Fila temporária para envio de mensagens. Pode ser de capacidade zero (envio bloqueante obrigatório),
capacidade limitada (envio fica bloquante se a fila estiver cheia) ou capacidade ilimitada (envio não
bloqueante sempre é possível).