Notas de aula do professor .

advertisement
Sistemas Operacionais – Filippe Jabour – v. 2.0.1
Universidade Severino Sombra – USS.
Universidade Presidente Antônio Carlos - UNIPAC
Sistemas Operacionais. Autor: Filippe Jabour. Versão: 2.0.1. Atualizada em: 01/03/2004.
Sistemas Operacionais
Índice
1.
Introdução: .................................................................................................................................................................... 2
1.1
Histórico:............................................................................................................................................................... 2
1.1.1
2ª geração, 1955 a 1965: ............................................................................................................................... 2
1.1.2
3ª geração, 1965 a 1980: ............................................................................................................................... 2
1.1.3
4ª geração, 1980 até hoje: .............................................................................................................................. 2
1.2
Conceitos básicos: ................................................................................................................................................. 3
1.2.1
Sistema Operacional: .................................................................................................................................... 3
1.2.2
Operação de sistemas computacionais: ......................................................................................................... 3
1.2.3
Chamadas de sistema (system calls):............................................................................................................. 3
1.2.4
Processo: ....................................................................................................................................................... 4
1.2.5
Shell: ............................................................................................................................................................. 4
1.3
Estrutura do S.O.: .................................................................................................................................................. 4
1.3.1
Sistemas monolíticos: .................................................................................................................................... 4
1.3.2
Sistemas em camadas: ................................................................................................................................... 4
1.3.3
Máquina virtual: ............................................................................................................................................ 5
1.3.4
Modelo Cliente-Servidor: .............................................................................................................................. 5
2
Processos:...................................................................................................................................................................... 5
2.1
Introdução: ............................................................................................................................................................ 5
2.1.1
Modelo de processo: ..................................................................................................................................... 6
2.1.2
Alternância entre processos: .......................................................................................................................... 6
2.1.3
Exercícios: ..................................................................................................................................................... 7
2.2
Threads ou processos leves: .................................................................................................................................. 8
2.3
Escalonamento de processos: ................................................................................................................................ 9
2.4
Métodos de escalonamento: .................................................................................................................................. 9
2.4.1
Primeiro a chegar, primeiro a ser servido (PCPS) (First in first out – FIFO):............................................... 9
2.4.2
Menor primeiro (MP): ................................................................................................................................. 10
2.4.3
Alocação por prioridade: ............................................................................................................................. 11
2.4.4
Alocação circular (AC) (Round Robin): ...................................................................................................... 11
2.4.5
Exercícios: ................................................................................................................................................... 12
3
Gerenciamento de Memória ........................................................................................................................................ 13
3.1
Fundamentos ....................................................................................................................................................... 13
3.2
Troca de Processos .............................................................................................................................................. 13
3.3
Alocação contígua de memória ........................................................................................................................... 13
3.3.1
Alocação com diversas partições ................................................................................................................ 14
3.4
Paginação ............................................................................................................................................................ 14
3.4.1
Método básico ............................................................................................................................................. 14
3.4.2
Páginas Compartilhadas .............................................................................................................................. 15
3.5
Segmentação ....................................................................................................................................................... 16
3.5.1
Proteção e compartilhamento ...................................................................................................................... 17
3.5.2
Fragmentação: ............................................................................................................................................. 17
4
Bibliografia ................................................................................................................................................................. 17
1
Sistemas Operacionais – Filippe Jabour – v. 2.0.1
1. Introdução:
1.1 Histórico:
1.1.1 2ª geração, 1955 a 1965:





Batch Systems e transistor.
Leitura de cartões de vários programas para fitas feita em computadores auxiliares.
O "ancestral" dos Sistemas Operacionais (S.O.) lê as fitas e executa os programas um a um, gravando
os resultados também em fita. Esta etapa é executada no computador principal.
Impressão dos resultados no computador auxiliar.
Comunicação entre computador auxiliar e computador central feita pelo operador.
1.1.2 3ª geração, 1965 a 1980:




Multiprogramação e circuito integrado
Computadores de uso geral (científico + comercial) compatíveis entre si (família) o que implicou em S.O.
muito complexos e com muitos erros. Mesmo assim foi introduzido um conceito de extrema importância,
a multiprogramação.
Objetivo da multiprogramação: Aproveitar momentos ociosos de CPU (tipicamente existentes durante
operações de I/O) para processar outros jobs (programas).
Como funciona a multiprogramação: Divisão da memória e carga de mais de um programa possibilitando
o chaveamento de um para outro durante os momentos de ociosidade citados anteriormente. Ver figura
1.
Programa 3
Partições de
memória
Programa 2
Programa 1
S.O.
Figura 1




É necessário que haja proteção de um programa com relação a outro para que não ocorra invasão de
outras áreas de memória. Aqui esta proteção era implementada em hardware.
Outra habilidade introduzida foi a capacidade de leitura dos programas dos cartões para o disco logo que
os mesmos eram trazidos para a sala do computador. Assim, quando um job terminava, outro poderia ser
carregado (spooling). Também se utilizava spooling para saída. Computadores auxiliares da 2ª geração
não eram mais necessários.
Surge a técnica de time-sharing ou compartilhamento de CPU. Cada usuário tem um terminal on-line e
todos compartilham a CPU.
Sistema operacional Multics é reescrito em C dando origem ao Unix.
1.1.3 4ª geração, 1980 até hoje:



Integração em larga escala (LSI e VLSI)
Surge o PC, muito mais barato do que os computadores das gerações anteriores. O uso do computador
de dissemina amplamente.
S.O. deve ser amigável (user-friendly) buscando dar comodidade ao usuário.
2
Sistemas Operacionais – Filippe Jabour – v. 2.0.1






Sistemas que surgem e/ou se popularizam: MS-DOS, Unix/Linux, Apple, Windows
95/98/2000/ME/CE/NT/XP
Nesta geração ocorre a descentralização do processamento.
S.O. de rede: Usuários estão cientes da existência de múltiplos computadores, podendo conectar-se a
máquinas remotas e utilizar recursos destas máquinas.
S.O. distribuídos: Aparecem para o usuário como um sistema convencional mas, na verdade, recursos
distribuídos estão sendo disponibilizados. O usuário não tem conhecimento da localização dos seu
arquivos nem do local onde seus programas estão sendo executados.
Nesta fase torna-se marcante a maior importância da comodidade do usuário sobre a eficiência do
sistema
Com a expansão dos dispositivos móveis de computação, S.O. específicos, com características próprias
de interface, economia de energia e utilização de recursos de conectividade vêm sendo desenvolvidos.
1.2 Conceitos básicos:
1.2.1 Sistema Operacional:




É difícil conceituar objetivamente S.O.. Serão colocadas a seguir algumas definições.
É o software que gerencia o hardware.
É um gerenciador de recursos, de processos, de segurança e de compartilhamento. Entenda-se por
recursos os arquivos, memória principal, periféricos como discos e impressoras, etc.
É um programa que controla e coordena o uso do hardware por vários programas aplicativos de vários
usuários.
Conjunto de módulos de software que rege a utilização dos recursos do sistema, resolve conflitos,
simplifica o uso da máquina e busca otimizar seu desempenho global.
1.2.2 Operação de sistemas computacionais:
Um sistema computacional moderno, de propósito geral, consiste em uma CPU e vários
controladores de dispositivos conectados por um barramento comum que oferece acesso a uma memória
compartilhada (ver [1], figura 2.1, p. 45).
A CPU e os controladores de dispositivos podem ser executados simultaneamente, competindo por
ciclos de memória. Para assegurar um acesso ordenado à memória compartilhada, existe um controlador de
memória, cuja função é sincronizar os acessos a ela.
Seqüência inicial de funcionamento de um computador e as etapas subseqüentes de operação do
sistema operacional.
1. O equipamento é ligado.
2. BIOS (Basic I/O System): Executa testes no sistema (hardware), reconhece controladores de
dispositivos, busca o primeiro programa a ser executado.
3. Este primeiro programa (programa de bootstrap), bastante simples, inicializa os valores de
alguns registradores, localiza, carrega e põe em execução o sistema operacional.
4. O núcleo do sistema operacional foi então carregado e fica em execução durante toda a
sessão de trabalho. Neste primeiro momento um processo do sistema operacional é iniciado
e fica aguardando a ocorrência de algum evento. A ocorrência de um evento é em geral
sinalizada por uma interrupção de hardware (enviada pelo barramento de sistema) ou de
software (através de uma operação especial denominada chamada de sistema – system
call). Podem gerar uma interrupção, a conclusão de uma operação de entrada e saída (E/S),
divisão por zero, acesso a uma posição inválida de memória, requisição a um serviço do
sistema operacional etc. Para cada interrupção existe uma rotina específica que irá tratá-la.
Quando ocorre uma interrupção, a CPU pára o que está fazendo e transfere imediatamente a
execução para uma posição fixa de memória onde está o endereço inicial da rotina de
tratamento.
1.2.3 Chamadas de sistema (system calls):
A interface entre o S.O. e os programas de usuário é definida pelo conjunto de instruções
estendidas que o S.O. proporciona. Exemplo: read(file,buffer,mbytes): chamada de sistema para ler um
arquivo de um certo tamanho para um determinado buffer.
3
Sistemas Operacionais – Filippe Jabour – v. 2.0.1
1.2.4 Processo:
É um programa (ou parte de um programa) em execução.
1.2.5 Shell:
É o prompt do sistema que aguarda a digitação de um comando. Quando este é digitado, o
interpretador de comandos traduz a linha digitada e o S.O. executa o comando.
1.3 Estrutura do S.O.:
1.3.1 Sistemas monolíticos:
Trata-se de um único módulo executável onde qualquer procedimento enxerga os demais e
pode executá-los livremente.
Podemos ter um nível de estruturação como descrito a seguir:
1. A máquina está em modo usuário executando um processo.
2. É executada uma instrução especial de interrupção conhecida como chamada de kernel ou chamada
de supervisor, comutando a máquina do modo usuário (nem todas as instruções são permitidas) para
o modo kernel ou modo monitor (todas as instruções são permitidas).
3. S.O. termina de executar as instruções desejadas em modo Kernel e retorna com a máquina para o
modo usuário, reiniciando a execução de um dado processo.
1.3.2 Sistemas em camadas:
Uma camada tem suas funções bem definidas e oferece serviços à camada superior. A camada
superior não precisa "se preocupar" como a camada inferior implementa um serviço, ela apenas utiliza tal
serviço. Um exemplo (Dijkstra, 1968):
Camada
5
4
Função
Operador
Programa usuário
3
Gerenciamento de I/O (entrada
e saída) (E/S)
2
Comunicação
Processo
1
Gerenciamento de processos
em
memória
e
disco
(paginação)
0
Alocação do processador e
multiprogramação
Operador
X
Observações
Processo de operação dos sistemas e programas
Não tem que se preocupar com gerência de processos, de
memória, de console ou de E/S.
Gerencia dispositivos de E/S e os respectivos buffers.
Acima desta camada, cada processo pode lidar com
dispositivos abstratos e amigáveis de E/S.
Manipula a comunicação entre cada processo e o console
do operador. Acima desta camada cada processo possui
virtualmente seu próprio console de operação.
Coloca os processos em memória e, caso não haja
espaço, partes deles (páginas) em disco. Não se preocupa
como e quando estes processos serão postos em
execução na CPU e quando serão retirados da CPU pois
isto é função da camada zero. Cuida para que, quando
necessário, as páginas certas estejam na memória.
Aloca CPU para os diversos processos baseado em
critérios de escalonamento (ex.: fatia de tempo) e em
interrupções. Proporciona a multiprogramação.
Tabela 1
O MULTICS (precursor do Unix) generalizou o esquema de camadas para uma organização em
anéis concêntricos. Os anéis internos são privilegiados com relação aos externos. Quando um procedimento
em um anel externo quer chamar outro em um anel interno, ele tem que fazer o equivalente a uma chamada
de sistema. Os parâmetros desta chamada são cuidadosamente verificados e validados antes da permissão
de execução.
4
Sistemas Operacionais – Filippe Jabour – v. 2.0.1
1.3.3 Máquina virtual:
Um módulo (monitor de máquina virtual) executa sobre o hardware básico e, através de
multiprogramação, oferece várias "cópias" virtuais deste hardware básico. Em cada uma destas cópias
(máquinas virtuais) é executado um S.O. (não necessariamente o mesmo) e ela se mostra aos níveis
superiores como se fosse o próprio hardware básico.
S.O.
MV 1
S.O.
S.O.
MV 2
MV 3
Monitor de máquina virtual
Hardware básico
.........
.........
Figura 2
1.3.4 Modelo Cliente-Servidor:
Migra diversas funções do S.O. para processos servidores a serem executados no modo usuário e
deixa menos atribuições para o kernel do S.O. (basicamente gerenciar a comunicação entre clientes e
servidores e executar instruções complexas típicas do modo kernel.)
Modo
usuário
Processo
Processo
Cliente
Cliente
......
Servidor
de terminal
......
Servidor
Servidor de
de
memória
arquivos
Kernel
Modo
Kernel
Figura 3
Se considerarmos que processos clientes e servidores podem estar rodando em máquinas
diferentes, temos uma extrapolação para Sistemas Distribuídos.
2 Processos:
2.1 Introdução:
Conceitualmente, Processo é a abstração de um programa (ou parte de um programa) em
execução. É um modelo apropriado para a compreensão da multiprogramação (presente em todos os S.O.
modernos).
Todos os computadores modernos podem fazer várias coisas ao mesmo tempo. Enquanto executa
um programa do usuário, um computador também pode estar lendo a partir do disco e dando saída a texto
para uma tela ou impressora. Em um sistema de multiprogramação, a CPU também alterna de um programa
para outro, executando cada um por dezenas ou centenas de milissegundos. Enquanto, estritamente falando,
em qualquer instante de tempo, a CPU está executando só um programa, no curso de 1 segundo, ela pode
funcionar para vários programas, dando aos usuários a ilusão de paralelismo. Às vezes, as pessoas falam de
pseudoparalelismo querendo referir-se a essa rápida alternância da CPU entre programas, em contraste
5
Sistemas Operacionais – Filippe Jabour – v. 2.0.1
com o paralelismo verdadeiro em hardware dos sistemas multiprocessadores (que têm duas ou mais CPUs
compartilhando a mesma memória física). Monitorar múltiplas atividades paralelas é um problema
complicado. Assim, com os anos, os projetistas de S.O. desenvolveram um modelo (processos seqüenciais)
que torna o paralelismo mais fácil de tratar. [2]
2.1.1 Modelo de processo:


Programa = Somatório de Processos
Processo = Código executável + Contador de programa + Valores de registradores + Área de dados
Estado da
CPU



Processos podem criar e destruir "N" processos filhos.
Processo bloqueado  o processo se colocou em estado de espera por algum evento externo
(entrada/saída de dados).
Diagrama de estados de um processo:
6
Novo
Terminado
Executando
1
3
2
4
Pronto
Bloqueado
5
Figura 4
1.
2.
3.
4.
5.
6.
Processo está sendo criado
Processo bloqueia para aguardar uma entrada
Escalonador dá a CPU a outro processo
Escalonador dá a CPU ao processo
A entrada aguardada em 2 torna-se disponível
Processo concluiu sua execução
2.1.2 Alternância entre processos:
Temos na figura 3 a representação de processos que executam programas usuários e processos que
executam serviços do S.O.. O kernel se encarrega basicamente de escalonar processos para o uso da CPU,
gerenciar interrupções e comunicação interprocessos. Diante deste cenário vamos analisar a alternância de
processos na CPU através de um exemplo extraído do S.O. Minix, uma variante simplificada no Unix.
Associada a cada dispositivo de E/S (drive de disquete, disco rígido, temporizadores, portas de
comunicação) existe uma interrupção (interrupt request – IRQ). O conjunto destas interrupções forma o vetor
de interrupção que contém o endereço de memória do procedimento que trata cada interrupção, ou seja, o
endereço da rotina de tratamento de cada operação de E/S. Veja a sequência.
1. Processo Pi executando.
2. IRQ de disco.
3. O hardware de interrupção grava o contador de programa (PC) e possivelmente outros dados em uma
pilha e salta para o vetor de interrupção.
6
Sistemas Operacionais – Filippe Jabour – v. 2.0.1
4. A execução salta para o endereço de memória apontado pelo vetor de interrupção, para a posição
correspondente à IRQ de disco.
5. O procedimento do item 4 inicia sua execução salvando todos os registradores em uma tabela de
processos que armazena informações sobre o estado dos processos. São elas: valor do contador de
programa (PC), dados sobre alocação de memória, status dos arquivos abertos, etc. Esta rotina é escrita
em Assembly e, neste caso, está salvando o estado de Pi.
6. O processo de disco passa de bloqueado para pronto.
7. O agendador é chamado. Geralmente os processos manipuladores de E/S têm prioridade mais alta.
8. O restante da rotina de tratamento de IRQ (em C) executa o acesso a disco (leitura ou escrita).
9. Pi é reescalonado e passa de bloqueado para pronto e logo retomará sua execução.
10. O estado de Pi é recuperado (rotina em Assembly) e Pi reassume a CPU.
2.1.3 Exercícios:
1. Diga o que é e comente as vantagens da utilização de multiprogramação pelos Sistemas Operacionais.
2. Considere os programas descritos abaixo:
Prg 1: 1-a) Recebe N números a partir do teclado.
1-b) Efetua cálculos matemáticos complexos com estes números.
1-c) Imprime em papel um relatório extenso como resultado.
Prg 2: 2-a) Executa a indexação de um arquivo de dados segundo um campo qualquer.
Prg 3: Enquanto existirem palavras
3-a) Busca palavra em um texto que já está na memória RAM
3-b) Imprime em papel a palavra
fim-enquanto
Segundo o princípio da multiprogramação e considerando que os 3 programas foram iniciados
aproximadamente ao mesmo tempo, organize os procedimentos 1-a, 1-b, 1-c, 2-a, 3-a e 3-b em uma ordem
coerente de execução na CPU. Considere que procedimentos ou processos podem utilizar a CPU e retornar
à CPU caso não tenham sido concluídos.
Teça comentários sobre sua solução.
3. Defina Sistema Operacional, em seguida ilustre os conceitos utilizados através de analogias práticas com
um Sistema Operacional que você conheça.
4. Um processo está em execução e é retirado da CPU. Nesta etapa o valor do contador de programa é
armazenado. Por quê?
5. Defina e explique as funções do vetor de interrupções.
6. Máxima eficiência X Comodidade do usuário. Comente este paralelo levando em conta inclusive fatores
históricos da evolução dos Sistemas Operacionais.
7. Defina Chamadas de Sistema (system calls).
8. Relacione as colunas:
1. Processo está utilizando a CPU
(
) Novo
2. Processo concluiu seu processamento
(
) Pronto
3. Processo foi retirado da CPU para que
(
) Bloqueado
(
) Terminado
o Sistema Operacional resolva uma
interrupção
relacionada
a
outro
processo
4. Usuário
acaba
de
comandar
a
7
Sistemas Operacionais – Filippe Jabour – v. 2.0.1
execução de um programa
5. Processo requisitou leitura de dados
cruciais
para
a
continuidade
(
) Executando
do
processamento
9. Qual o principal objetivo (vantagem) da multiprogramação?
10. Como funciona a multiprogramação?
11. O que é mais importante nos Sistemas Operacionais modernos, máxima eficiência ou comodidade do
usuário? Comente sua resposta.
12. Como age o Sistema Operacional com relação aos recursos de hardware disponíveis? Quais são estes
recursos de hardware?
13. Defina processo.
14. Fale sobre o modelo Cliente-Servidor de Sistemas Operacionais.
15. Dentro do contexto desta disciplina, explique o que é proteção.
16. Complete a figura com as 6 setas que representam as transições de estado que pode sofrer um
processo. Diga o que está ocorrendo em cada uma destas transições de estado.
Terminado
Novo
Executando
Pronto
Bloqueado
2.2 Threads ou processos leves:
Se dentro de um processo temos múltiplas linhas de controle e múltiplos contadores de programa,
mas com um único espaço de endereçamento, podemos ter múltiplos threads compondo um processo. S.O.
modernos oferecem suporte a threads. Podemos entender threads como fluxos de execução distintos
pertencentes ao mesmo processo.
Um exemplo de boa aplicação para threads é o processo servidor de arquivos que trabalha com
múltiplas requisições e uma área de armazenamento, no caso de um chache de disco em RAM. Quando um
thread bloqueia em espera a uma E/S, o processo continua executando outros threads.
Outro exemplo é o tratamento de múltiplas conexões TCP em um navegador Web com uma conexão
por imagem.
No caso de threads temos uma tabela de estado de threads (contador de programa e registradores).
Os threads podem estar nos estados executando, pronto ou bloqueado.
O esquema de threads pode ser gerenciado inteiramente no espaço usuário. O próprio processo
escalona outro thread quando aquele em execução está prestes a bloquear. Em outros casos o próprio S.O.
8
Sistemas Operacionais – Filippe Jabour – v. 2.0.1
escalona diretamente os threads, alternando mesmo entre threads de processos distintos. Existem
vantagens nas duas formas e ambas são utilizadas.
Existem questões complexas de integridade de informações quando se usa threads. Por exemplo,
dois threads do mesmo processo bloqueados por espera ao teclado: quando chegar a entrada de teclado,
qual dos threads deve captura-la?
Existem vários outros problemas a serem tratados e a introdução do uso de threads exige uma
revisão geral no S.O..
2.3 Escalonamento de processos:
Podemos ter em um mesmo instante mais de um processo no estado Pronto (ver figura 4), ou seja,
vários processos em condição de rodar. Nesta situação o S.O. deve decidir qual deles irá assumir a CPU. A
parte do S.O. a quem cabe tomar esta decisão é o escalonador. O escalonador executa o algoritmo de
escalonamento. Os processos prontos ficam armazenados em uma fila e é sobre esta fila que o
escalonador toma a sua decisão.
Existem também filas para a utilização de outros dispositivos, por exemplo, uma fila de E/S onde
estão os processos que aguardam sua vez de utilizarem recursos de E/S.
Vejamos quais as características que devem estar presentes em um bom algoritmo de
escalonamento:
1. Justiça: garantir que todos os processos do sistema tenham chances iguais de usar o
processador, salvo em situações onde exista prioridade. Neste último caso, a justiça está em
oferecer aos processos de uma mesma classe (mesma prioridade) chances iguais de uso da
CPU.
2. Eficiência (utilização da CPU): manter o processador ocupado durante o maior tempo possível.
3. Tempo de resposta: minimizar o tempo de resposta para os usuários interativos.
4. Turnaround: minimizar o tempo que os usuários batch devem esperar pela saída.
5. Throughput (vazão) (produtividade): maximizar o número de processos atendidos na unidade
de tempo.
Podemos observar que existem conflitos a serem tratados. Os itens 3 e 4, por exemplo, são
conflitantes. Se não executarmos nenhum job batch, os usuários interativos terão melhor resposta do
sistema. De um modo geral, sempre que se oferta recursos adicionais a uma classe de usuários, outra classe
está sendo prejudicada.
Outro fator importante é o fato dos processos terem comportamentos únicos e imprevisíveis. O
escalonador não consegue prever se um processo irá gastar muito tempo com E/S ou se tentará permanecer
muito tempo na CPU. Quando coloca um processo para rodar, o escalonador não sabe quanto tempo o
processo irá demorar para bloquear e deve se precaver para que ele não fique tempo demais na CPU. Os
computadores modernos possuem um relógio interno que gera periodicamente um sinal de interrupção
chamado interrupção de tempo. A freqüência de geração desta IRQ de tempo pode ser fixo ( 50 ou 60 Hz) ou
pode ser programada pelo S.O. no hardware, caso este permita. A cada IRQ de tempo o S.O. assume a CPU
e decide se aquele processo continua executando ou se passa para o estado de Pronto.
A estratégia de permitir a suspensão temporária de processos que poderiam continuar executando é
chamada de escalonamento preemptivo. Esta técnica é, sem dúvida, a mais adequada para sistemas de
uso geral.
2.4 Métodos de escalonamento:
A alocação da CPU trata do problema de decidir qual dos processos na fila de prontos vai ser
executado pela CPU. A seguir serão discutidos diversos deles.
2.4.1 Primeiro a chegar, primeiro a ser servido (PCPS) (First in first out –
FIFO):
Como o próprio nome diz, os processos serão atendidos na mesma ordem em que chegam à fila de
prontos. Exemplo:
Ordem de chegada
Processo
1º
2º
3º
P1
P2
P3
Duração da fase de
uso da CPU (ms)
24
3
3
9
Sistemas Operacionais – Filippe Jabour – v. 2.0.1
Tabela 2
Resultado: P1 assumirá a CPU imediatamente, P2 em 24 ms e P3 em 27 ms, sem considerar o
tempo gasto com mudança de contexto. O tempo médio de espera é de ( 0 + 24 + 27 ) / 3 = 17 ms.
Se os processos entram na fila na ordem P2, P3 e P1 o resultado para o tempo de espera seria: P2 =
0 , P3 = 3 e P1 = 6 e a média seria de 3ms.
Este algoritmo é não-preemptivo. Uma vez assumindo a CPU, um processo só sai quando termina
sua execução ou quando bloqueia por uma requisição sua de E/S. Ele não é retirado por término da sua fatia
de tempo.
Este algoritmo apresenta problemas diante de processos que requerem muito uso da CPU e pouca
E/S. Estes processos ficarão muito tempo na CPU fazendo com que os outros permaneçam muito tempo na
fila de espera. Nos sistemas de tempo compartilhado (time-sharing), onde se espera uma alocação regular
da CPU entre os vários usuários seria desastroso permitir que um processo assumisse a CPU por um longo
período de tempo.
2.4.2 Menor primeiro (MP):
Nesta abordagem é atribuída a cada processo a duração da sua próxima fase de uso da CPU (D P).
Quando fica disponível, a CPU é alocada ao processo com menor duração da próxima fase de uso. Se este
valor for igual para dois ou mais processos aplica-se o esquema PCPS. Note que o critério é a duração da
próxima fase de uso da CPU e não o tempo total de execução do processo. Vamos ao exemplo:
Processo
P1
P2
P3
P4
Duração da próxima
fase de uso da CPU
(ms)
DP1 = 6
DP2 = 8
DP3 = 7
DP4 = 3
Tabela 3
Resultado: P4 é atendido imediatamente, P1 em 3 ms, P3 em 9 ms e P2 em 16 ms, sem considerar o
tempo gasto com mudança de contexto. O tempo médio de espera é de 7 ms enquanto seria de 10,25 ms se
estivéssemos utilizando PCPS.
A grande dificuldade deste algoritmo é determinar os valores de DP para cada processo P.
Este algoritmo é utilizado freqüentemente na alocação de processos que demandam muito tempo de
processamento. Nestes casos uma opção é o próprio usuário determinar o valor de D P.
Para ser utilizado na prática, este esquema tem que gerar o valor de D P. O que se faz é buscar uma
boa estimativa para este valor. É esperado, para um dado processo P, que o valor de D P seja similar aos
valores de fases anteriores de uso da CPU. Portanto, por intermédio do cálculo de aproximações para D P ,
podemos escolher o processo que, segundo nossa previsão, tenha o menor D P. Geralmente se utiliza a
média exponencial de durações medidas em fases anteriores. Seja t n a duração da enésima fase de uso da
CPU (informação mais recente), n representa a história passada, e seja n+1 o valor previsto para a duração
da n+1-ésima fase de uso da CPU. Então, para  entre 0 e 1, temos:
n+1 =  tn + (1 - ) n
Equação 1
O algoritmo MP pode ser tanto preemptivo quanto não-preemptivo.
Vamos a outro exemplo:
Processo
Tempo de chegada
P1
P2
P3
P4
0
1
2
3
Tabela 4
Duração da próxima
fase de uso da CPU
(ms)
DP1 = 8
DP2 = 4
DP3 = 9
DP4 = 5
Para alocação MP preemptiva temos o seguinte resultado (diagrama de Gantt):
10
Sistemas Operacionais – Filippe Jabour – v. 2.0.1
P1
0
P2
P4
1
P1
5
P3
10
17
26
Figura 5
O tempo de espera médio para este exemplo é ((10-1)+(1-1)+(17-2)+(5-3)) / 4 = 26 / 4 = 6,5 ms. Para
um esquema de alocação não-preemptivo o tempo de espera médio seria de 7,75 ms.
2.4.3 Alocação por prioridade:
Uma prioridade é associada a cada processo, sendo a CPU alocada ao processo que tem a maior
prioridade. Processos com prioridades iguais são enfileirados e atendidos segundo um critério secundário
(PCPS por exemplo). Veja o exemplo abaixo supondo que todos os processos chegaram à fila de prontos em
um tempo inicial zero:
Processo
Duração da fase de
uso da CPU (ms)
10
1
2
1
5
Tabela 5
P1
P2
P3
P4
P5
P2
0
1
P5
Prioridade
3
1
3
4
2
P1
P3
6
16
P4
18
19
Figura 6 – Diagrama de Gantt
O tempo de espera médio é de 8,2 ms.
A alocação por prioridade pode ser tanto preemptiva quanto não-preemptiva.
Problemas neste algoritmo estão relacionados com o abandono de processos de baixa prioridade,
que podem nunca assumir a CPU devido à existência contínua de processos de alta prioridade. Uma solução
pode ser o aumento de prioridade com o envelhecimento do processo.
A prioridade dos processos pode ser definida internamente pelo S.O. ou já vir definida por alguma
entidade externa.
2.4.4 Alocação circular (AC) (Round Robin):
Este algoritmo é um dos mais antigos, sendo simples, justo e muito utilizado.
Cada processo tem um intervalo de tempo durante o qual poderá utilizar a CPU (um quantum). Se o
seu quantum terminou e ele não concluiu seu processamento, o processo é retirado da CPU e vai para o final
da fila de prontos (esquema preemptivo). Se o processamento terminou ou bloqueou antes de esgotado o
quantum de tempo a comutação para outro processo é imediata.
Neste esquema, tudo o que o escalonador tem que fazer é manter uma lista de processos prontos e
gerenciar o rodízio. Veja a figura 7.
Próximo processo
A
G
Processo Corrente
D
F
B
t=x
11
Sistemas Operacionais – Filippe Jabour – v. 2.0.1
B
A
G
D
F
t = x + quantum(B)
Figura 7
A determinação do tamanho do quantum é importante no algoritmo Round Robin. Toda vez que se
alterna entre processos gasta-se tempo com tarefas burocráticas: salvar registradores, mapas de memória,
atualização de tabelas e listas. É a chamada troca de contexto. Vamos analisar algumas situações supondo
o tempo para troca de contexto valendo 5 ms:
Valor do
quantum (em
ms)
20
500
Overhead (porcentagem do
tempo útil do processador gasto
com escalonamento de processos)
Observações
20%
Menos de 1%
100
menos de 5%
Overhead alto
Overhead baixo. Entretanto, um alto valor para o
Quantum pode fazer com que processos esperem
muito tempo até poderem usar a CPU. Imagine 10
processos iniciados ao mesmo tempo, o último da fila
de prontos terá que esperar quase 5 s para utilizar a
CPU pela primeira vez (caso cada um dos outros
utilizem 100% do seu quantum), o que é inadmissível.
Devemos balancear o valor do quantum de forma a
otimizar o overhead com a espera pela CPU por parte
dos processos. Este valor costuma ser uma boa
solução de compromisso mas sempre cabe uma
análise cuidadosa para os diversos casos.
Tabela 6
A seguir mais um exemplo (com o quantum valendo 4 ms):
Processo
P1
P2
P3
P1
0
P2
4
P3
7
Duração da fase de
uso da CPU (ms)
24
3
3
Tabela 7
P1
10
P1
14
P1
18
P1
22
P1
26
30
Figura 8 – Diagrama de Gantt
O tempo de espera médio é (6+4+7) / 3 = 17 / 3 = 5,66 ms.
2.4.5 Exercícios:
1 – Comente as diferenças de requisitos de escalonamento que existem entre processos oriundos de
programas interativos e processos de programas que rodam em segundo plano sem interagir com usuários.
2 – Se os processos P1, P2 e P3 estão disputando a CPU e PE é o processo escalonador, crie uma
seqüência qualquer de utilização da CPU que seja coerente.
3 – O que é um esquema preemptivo de alocação de CPU?
4 – Qual o principal problema do algoritmo PCPS?
5 – Preencha a tabela abaixo com os valores previstos para as etapas de uso da CPU. Utilize o método de
média exponencial onde a duração da última etapa de uso da CPU tem o mesmo peso que a história
passada. A história passada é definida como a média de todas as fases de uso da CPU anteriores.
Fases de uso da
4
6
4
6
4
13
13
13
...
12
Sistemas Operacionais – Filippe Jabour – v. 2.0.1
CPU (ti)
Previsões (i)
10
...
3 Gerenciamento de Memória
3.1 Fundamentos
Memória: A CPU busca instruções na memória de acordo com o contador de instruções do programa
em execução. Essas instruções podem buscar novos valores em endereços específicos de memória e
armazenar novos valores em endereços específicos da memória.
3.2 Troca de Processos
Para que um processo seja executado, seu código precisa estar armazenado na memória principal,
tipicamente a memória RAM.
Enquanto não estiver com o controle da CPU, o código de um processo pode ser transferido
temporariamente para uma memória secundária (disco por exemplo). Posteriormente este código é
recarregado na memória principal para que o processo continue sua execução. O ideal é que sempre haja na
memória principal (memória RAM) um processo pronto para ser executado, quando o escalonador quiser
alocar a CPU a um processo. Esta troca recebe o nome de swapping.
Vejamos algumas situações possíveis:
a) O escalonador decidiu que o processo P que está no início da fila de prontos deve assumir a CPU.
O código deste processo está na memória principal. O que ocorre: O Despachante (dispatcher) é
chamado, faz a troca de contexto e põe o processo P em execução.
b) O escalonador decidiu que o processo P que está no início da fila de prontos deve assumir a CPU.
O código deste processo está na memória secundária. Existe espaço livre na memória principal para
a alocação (ou carga) do código do processo. O que ocorre: O código do processo P e transferido da
memória secundária para a principal (de disco para RAM), o Despachante é chamado, faz a troca de
contexto e põe o processo P em execução.
c) O escalonador decidiu que o processo P que está no início da fila de prontos deve assumir a CPU.
O código deste processo está na memória secundária. Não existe espaço livre na memória principal
para a alocação (ou carga) do código do processo. O que ocorre: Algum outro processo é removido da
memória principal, o código do processo P e transferido da memória secundária para a principal (de
disco para RAM), o Despachante é chamado, faz a troca de contexto e põe o processo P em execução.
Este sistema de troca de processos envolve grande atraso gerado pela leitura de processos em disco
(memória secundária) e a sua carga em memória RAM (memória principal). Entretanto, é necessário usar
este esquema para que o número de processos disputando a CPU em um sistema com multiprogramação
não fique limitado pela quantidade de memória RAM existente no sistema, ou seja, no computador. È
recomendável que o tamanho do Quantum em um sistema de alocação circular de CPU seja bem maior que
o tempo médio de carga de processos do disco para a RAM. Este tempo médio é função do tamanho médio
dos processos e da taxa média de acesso ao disco.
Com o grande aumento da quantidade de memória RAM disponíveis nos computadores atuais, este
modelo tradicional de swapping vem sendo menos utilizado. Isto se dá devido aos grande atraso que
acarretam na execução dos processos.
Unix: Muitas versões do Unix mantém a troca de processos normalmente desabilitada. Quando muitos
processos estão em execução e a utilização de memória ultrapassa um determinado limite, a troca e
habilitada temporariamente. Quando a carga do sistema diminui a função é novamente desabilitada.
3.3 Alocação contígua de memória
A memória principal é normalmente dividida em duas partes. A primeira é usada para armazenar o
sistema operacional e a segunda para processos de usuários. Na alocação contígua, o processo é carregado
em memória na forma de um único bloco, ou seja, não é dividido em duas partes.
13
Sistemas Operacionais – Filippe Jabour – v. 2.0.1
3.3.1 Alocação com diversas partições
Antes de analisar este esquema precisamos considerar a necessidade do código e dos dados do
sistema operacional serem protegidos. Esta proteção deve se dar de maneira a evitar que eles possam
(acidentalmente ou maliciosamente) ser mudados por processos de usuários. É necessário também proteger
os processos dos usuários uns dos outros.
Endereço lógico: São os endereços de memória usados e gerados pelos programas em execução.
Endereço físico: São os endereços de memória reais, efetivamente acessados na memória RAM.
O mapeamento entre endereços lógicos e físicos é feito pela Unidade de Gerenciamento de Memória
(UGM), um dispositivos de hardware.
Exemplo:
Registrador base = 14000
Endereço gerado pelo programa usuário: 0
Endereço físico gerado pela UGM: 14000
Registrador base = 14000
Endereço gerado pelo programa usuário: 346
Endereço físico gerado pela UGM: 14346
A proteção pode ser feita utilizando-se um registrador base e um registrador limite.
O registrador base contém o valor do menor endereço físico. O registrado limite contém o tamanho do
intervalo dos endereços lógicos. Desta forma pode-se garantir que o programa usuário não acessará
qualquer endereço de memória fora da faixa a ele reservada.
Exemplo:
Registrador base = 300040
Valor do registrador limite: 120900
Espaço lógico de endereçamento do processo: De 300040 a (300040 + 120900) , ou seja, de 300040 a
420940.
Agora que analisamos brevemente a questão relacionada à proteção, vamos estudar a forma mais
simples de alocação, aquela em que as partições possuem tamanho fixo. Cada partição pode conter
apenas um processo. O grau de multiprogramação é limitado ao número de partições. Quando uma partição
está livre, um processo é selecionado na fila de entrada (em disco) e armazenado nesta partição. Quando o
processo termina a sua partição é liberada. Este esquema não é mais utilizado.
Uma generalização do esquema acima é aquela em que o tamanho da partição não é fixo. O sistema
operacional mantém uma tabela com as áreas livres e ocupadas da memória. Quando um processo precisa
de memória, um espaço de memória suficiente é procurado. Se for encontrado, o espaço é alocado ao
processo.
Este método leva à fragmentação da memória. A memória fragmentada pode ter vários espaços de
memória que agrupados poderiam comportar um novo processo (Fragmentação Externa). Uma solução é a
compactação (faça uma analogia com a desfragmentação de disco). A compactação implica no
deslocamento de processos de um ponto para outra da memória e isto só é possível se o método de
endereçamento for dinâmico, ou seja, ajustado em tempo de execução.
3.4 Paginação
Outra solução para o problema da fragmentação externa é permitir que o espaço de endereçamento
lógico do processo seja não contíguo. Uma maneira de implementar esta solução é a utilização de um
mecanismo de paginação. Este método é muito utilizado.
3.4.1 Método básico
A memória lógica é dividida em partes do mesmo tamanho, chamadas páginas. A memória física é
dividida em partes do mesmo tamanho das páginas, chamadas blocos. Para a execução de um processo,
suas páginas, armazenadas em memória secundária, são carregadas em quaisquer blocos disponíveis na
memória. A memória secundária também é dividida em partes do mesmo tamanho que os blocos de
memória.
Todo endereço gerado pela CPU é dividido em duas partes: número da página (n) e posição na
página (p). O número da página (n) é usado como índice em uma tabela de páginas. A tabela de páginas
contém o endereço base de cada página na memória física, ou seja, endereço base do bloco
14
Sistemas Operacionais – Filippe Jabour – v. 2.0.1
correspondente à página. Este endereço base é combinado (somado) com a posição (p) para definir o
endereço de memória que é enviado à unidade de memória.
O tamanho da página (e conseqüentemente do bloco) é definido pelo hardware.
Páginas
0
1
2
3
Tabela de páginas
Página
0
1
2
3
Blocos
Bloco
1
4
3
7
0
1
2
3
4
5
6
7
Memória
Lógica
Página armazenada no
bloco
Página 0
Página 2
Página 1
Página 3
Memória Física
Figura 9
Neste esquema não ocorre fragmentação externa. Entretanto, ocorre um outro tipo de fragmentação, a
chamada Fragmentação Interna. Esta ocorre quando um processo precisa de uma quantidade de memória
que não é igual a uma quantidade inteira de blocos. Desta forma, o último bloco alocado não será totalmente
ocupado. Veja o exemplo:
Tamanho do bloco = 2048 bytes
Processo precisa de 72766 bytes
Número de páginas necessárias = 36 , ou seja, 36 x 2048 = 73728
Fragmentação interna com ( 73728 – 72766 ) = 962 bytes não usados.
Podemos então fazer a seguinte análise:
 Tamanho de página menor implica em menor perda de memória por fragmentação interna.
 Entretanto, tamanho de página menor implica em tabela de páginas maior e maior custo de
controle.
 E ainda, tamanho de página maior implica em otimização no acesso a disco (maior volume de
dados a transferir).
No ano 2000, o tamanho de páginas era de 2 ou 4 Kbytes. A maioria dos computadores modernos usa
tabelas de páginas muito grandes (por exemplo, com um milhão de entradas).
Quando um processo fica pronto para ser executado, seu tamanho, em número de páginas, é
examinado. A seguir, as páginas são carregadas nos blocos disponíveis.
 Visão da memória por parte do programa usuário: Espaço único e contíguo.
 O que ocorre de fato: Programa espalhado pela memória, em meio a outros programas.
A tradução de endereços é feita pelo hardware. O mapeamento é escondido do usuário e controlado
pelo Sistema Operacional.
3.4.2 Páginas Compartilhadas
Outra vantagem do mecanismo de paginação é a possibilidade do compartilhamento de código.
Conceito: Código reentrante (ou código puro): Código que não modifica a si próprio, ou seja, ele
nunca é modificado durante a execução.
Se um programa tiver código reentrante, dois ou mais processos podem executar o mesmo código
“simultaneamente”. Á área de dados é distinta para cada processo, mas o código executável (reentrante) é
único, e carregado uma única vez na memória. As páginas relativas ao código executável constam da tabela
de páginas de todos os processos que as utilizam.
Exemplo: Editor de texto com código reentrante de 150 K e área de dados de 50 K. 40 usuários
utilizando o editor em um ambiente de tempo compartilhado, seriam necessários 200 K x 40 = 8000 K. Se o
código executável for compartilhado, serão consumidos apenas ( 50 K x 40 ) + 150 K = 2150 K.
15
Sistemas Operacionais – Filippe Jabour – v. 2.0.1
3.5 Segmentação
Os programas são divididos em segmentos de tamanhos diferentes. A memória é acessada por um
endereço lógico representado pela dupla <número do segmento, posição no segmento>.
Comumente o programa do usuário é compilado e o compilador constrói automaticamente os
segmentos.
Exemplo:
Pilha
Subrotina
Segmento 3
Segmento 0
Tabela de
símbolos
Tabela de segmentos
Segmento Limite
Base
0
1000
1400
1
400
6300
2
400
4300
3
1100
3200
4
1000
4700
Segmento 4
Função Sqrt
1400
Segmento 1
Programa
Principal
Segmento 0
2400
Segmento 2
3200
Espaço de endereço lógico
Segmento 3
4300
Segmento 2
4700
Segmento 4
5700
6300
6700 Segmento 1
Memória Física
Figura 10
A tabela de segmentos contém o endereço físico do início do segmento (Base) e o tamanho do
segmento (limite).
O segmento 2 tem um tamanho de 400 bytes e começa na posição 4300 da memória.
Uma referência ao byte 53 do segmento 2 é transformada no endereço físico 4300 + 53 = 4353.
Uma referência ao segmento 3, byte 852, é mapeada em 3200 + 582 = 4052.
16
Sistemas Operacionais – Filippe Jabour – v. 2.0.1
Uma referência ao byte 1222 do segmento 0 provocaria uma interrupção de software, uma vez que esse
segmento possui apenas 1000 bytes.
3.5.1 Proteção e compartilhamento
Os segmentos podem ter atributos diferentes quanto ao acesso. Em outras palavras, segmentos de
código (ou se instruções) terão permissão para “somente leitura” ou “somente execução”, enquanto
segmentos de dados poderão receber gravação. Com isto temos proteção das áreas de instruções.
O mesmo esquema descrito em 3.4.2 pode ser implementado com segmentação. Neste caso, um editor
de textos completo, de tamanho possivelmente grande, composto por vários segmentos, pode ser executado
por vários usuários em um ambiente de tempo compartilhado. Neste caso, os segmentos de código
executável serão compartilhados por todos os usuários e a área de dados irá gerar segmentos de dados
distintos para cada programa usuário.
3.5.2 Fragmentação:
A segmentação pode levar à fragmentação externa de memória.
4 Bibliografia
[1] Abraham Silberschatz e Peter Baer Galvin. Sistemas Operacionais: Conceitos. Makron Books do Brasil
Ltda. Quinta Edição.
[2] Abraham Silberschatz, Peter Baer Galvin e greg Gagne. Sistemas Operacionais: Conceitos e Aplicações.
Rio de Janeiro. Campus. 2000.
[3] Tanenbaum, Andrew S. e Woodhull, Albert S. Sistemas Operacionais: projeto e implementação; trad.
Edson Furmankiewics - Porto Alegre: Bookman, 2000. Segunda edição.
[4] Tanenbaum, Andrew S. - Sistemas Operacionais Modernos - Rio de Janeiro - LTC - 1992/1999.
[5] Machado, Francis B. e Maia, Luiz Paulo - Arquitetura de Sistemas Operacionais – LTC – 2ª edição.
17
Download