Arquitetura de Sistemas Operacionais

Propaganda
Arquitetura de Sistemas Operacionais
1. Histórico ............................................................................................................
3
2. Tipos de Sistemas Operacionais
.....................................................................
2.1 Sistemas Monoprogramáveis .....................................................................
2.2 Sistemas Multiprogramáveis .....................................................................
2.2.1 Sistemas Batch
.....................................................................
2.2.2 Sistemas de Tempo Compartilhado
........................................
2.2.3 Sistemas de Tempo Real ...........................................................
2.3 Sistemas Multiprocessados .....................................................................
4
4
5
6
7
7
8
3. Sistemas Multiprogramáveis ...............................................................................
3.1 Tratamento de Interrupções e Exceções ..................................................
3.2 Buffer
...................................................................................................
3.3 Spool
...................................................................................................
3.4 Reentrância
.........................................................................................
3.5 Segurança e Proteção do Sistema ............................................................
3.6 Operações de E/S
................................................................................
10
11
12
12
13
14
17
4. Estrutura do Sistema Operacional
......................................................................
4.1 Estrutura do Sistema ................................................................................
4.2 Funções do Sistema ................................................................................
4.3 System Calls
..........................................................................................
4.4 Modos de Acesso
................................................................................
4.5 Arquiteturas: Sistemas monolíticos, em camadas e microkernel ......................
17
17
18
19
20
21
5. PROCESSO
....................................................................................................
5.1 Componentes do processo .......................................................................
5.2 Estados do processo .................................................................................
5.3 Mudanças de estado .................................................................................
5.4 Tipos de processo
.................................................................................
24
24
26
27
28
6. Gerência do Processador
........................................................................................
6.1 Funções .............................................................................................................
6.2 Critérios de Escalonamento .............................................................................
6.3 Escalonamentos Não-Preemptivos e Preemptivos
...................................
29
29
29
30
7. Gerência de Memória / Memória Virtual
...................................................................
7.1 Introdução
...................................................................................................
7.2 Funções ..............................................................................................................
7.3 Alocação Contígua Simples ..............................................................................
7.4 Segmentação de programas ..............................................................................
34
34
34
34
35
1
7.5 Alocação Particionada Estática Absoluta e Relocável ....................................
7.6 Alocação Particionada Dinâmica
...................................................................
7.7 Estratégias de Alocação de Partição
........................................................
7.8 Swapping
...................................................................................................
7.9 Memória Virtual ...................................................................................................
7.10 Algoritmos de substituição de páginas
........................................................
36
38
39
39
40
43
8. Gerência de sistemas de Arquivos ..............................................................................
8.1 Estrutura de diretórios .........................................................................................
8.2 Sistemas de alocação de arquivos ....................................................................
8.3 Gerência de espaço livre
...............................................................................
8.4 Proteção de acesso ..........................................................................................
45
45
45
46
47
9. BIBLIOGRAFIA ...............................................................................................................
48
2
1. Histórico
Antes da década de 50, os computadores eram muito difíceis de serem programados. Era
necessário conhecer totalmente sua arquitetura, e tal operação era efetuada em painéis com
cerca de 6.000 conectores, em linguagem de máquina. Nesta fase os computadores não
possuíam ainda dispositivos para interagir com o usuário, como teclados e monitores.
Na década de 50, já com a utilização de transistores, sucedeu-se um grande avanço
tecnológico, melhorando a velocidade dos processadores e a capacidade dos meios de
armazenamento, em especial a memória e os discos magnéticos.
Por volta de 1953 foi introduzido o primeiro sistema operacional, um programa de
controle que permitia uma interação, mesmo que limitada, entre o operador e a máquina,
otimizando a execução das tarefas. Em 1959 foi criada uma versão de sistema operacional que
já implementava conceitos de memória virtual, conceito este largamente utilizado nos sistemas
atuais.
Na década de 60, a partir do surgimento dos circuitos integrados, foi possível difundir u
uso de sistemas computacionais em empresas, com diminuição de custos e tamanho dos
equipamentos. Além disso, esta década presenciou inúmeras inovações na área de sistemas
operacionais, presentes até hoje, como os ambientes de multitarefa, multiprogramação,
multiprocessamento e time-sharing, tendo o desenvolvimento destas técnicas avançado até o
meado da década de 70, onde também foram implementadas as tecnologias baseadas em
arquitetura VLSI (chips), as primeiras redes de computadores, e o desenvolvimento de diversas
linguagens de programação de alto nível.
A década de 80 foi marcada pela criação dos microcomputadores, baseados em
microprocessadores de uso pessoal. Liderados pela IBM, diversos fabricantes seguiram por essa
linha, porém alguns deles não abandonando a fabricação dos computadores de grande porte,
como foi o caso da própria IBM.
Nota-se que, a partir do meado da década de 80, acontece uma divisão de águas, com a
indústria passando a produzir equipamentos de grande porte e muitos modelos de
microcomputadores, que também precisavam de sistemas operacionais bastante evoluídos.
Foram, então, utilizadas as técnicas modernas já existentes nos ambientes de grande porte na
implementação de sistemas operacionais para os microcomputadores, com versões diversas,
todas inicialmente monousuário/monotarefa (devido à baixa capacidade de armazenamento dos
micros, naquela época). Com o avanço da tecnologia, os micros ganharam discos rígidos e
outros periféricos, possibilitando a criação de sistemas operacionais mais evoluídos nesta
categoria de computadores, quando surgiram os sistemas monousuário/multitarefa, que
executam até hoje.
3
Cronologia
Grande porte (mainframes)
1990
1950
1960
1º Sistema Operacional
Monoprogramável
Monotarefa
1970
Sistemas
Multitarefa
1980
Sistemas
Multiprogramáveis
Multitarefa
Introduzido o
conceito de
Memória Virtual
Microcomputadores
2. Tipos de Sistemas Operacionais
Tipos de
Sistemas Operacionais
Sistemas
Monoprogramáveis/
Monotarefa
2.1
Sistemas
Multiprogramáveis/
Multitarefa
Sistemas
Com Múltiplos
Processadores
Sistemas Monoprogramáveis/Monotarefa
Os primeiros sistemas operacionais eram voltados tipicamente para a execução de um
único programa. Qualquer outra aplicação, para ser executada, deveria aguardar o término do
programa corrente. Neste tipo de sistema, o processador, a memória e os periféricos
permanecem exclusivamente dedicados à execução de um único programa.
Os sistemas monoprogramáveis estão diretamente ligados ao surgimento, na década de
50/60, dos primeiros computadores. Embora os sistemas operacionais já tivessem evoluído com
as tecnologias de multitarefa e multiprogramáveis, os sistemas monoprogramáveis voltaram a
ser utilizados na plataforma de microcomputadores pessoais e estações de trabalho devido à
baixa capacidade de armazenamento destas máquinas, na época.
4
Era muito clara a desvantagem deste tipo de sistema, no que diz respeito à limitação de
tarefas (uma de cada vez), o que provocava um grande desperdício de recursos de hardware.
_______
_______
_______
_______
_______
CPU
Memória
Principal
Dispositivos E/S
Programa/Tarefa
Sistema Monoprogramável/Monotarefa
Comparados a outros sistemas, os monoprogramáveis são de simples implementação,
não existindo muita preocupação com problemas decorrentes do compartilhamento de recursos
como memória, processador e dispositivos de E/S.
2.2
Sistemas Multiprogramáveis/Multitarefa
Constituindo-se uma evolução dos sistemas monoprogramáveis, neste tipo de sistema os
recursos computacionais são compartilhados entre os diversos usuários e aplicações: enquanto
um programa espera por um evento, outros programas podem estar processando neste mesmo
intervalo de tempo. Neste caso, podemos observar o compartilhamento da memória e do
processador. O sistema operacional se incumbe de gerenciar o acesso concorrente aos seus
diversos recursos, como processador, memória e periféricos, de forma ordenada e protegida,
entre os diversos programas.
As vantagens do uso deste tipo de sistema são a redução do tempo de resposta das
aplicações, além dos custos reduzidos devido ao compartilhamento dos recursos do sistema
entre as diferentes aplicações. Apesar de mais eficientes que os monoprogramáveis, os sistemas
multiprogramáveis são de implementação muito mais complexa.
5
_______
_______
_______
_______
_______
_______
_______
_______
_______
_______
CPU
Programa/Tarefa
Programa/Tarefa
Memória
Principal
_______
_______
_______
_______
_______
Dispositivos E/S
_______
_______
_______
_______
_______
Programa/Tarefa
Programa/Tarefa
Sistema Multiprogramável/Multitarefa
Os sistemas multiprogramáveis/multitarefa podem ser classificados de acordo com a
forma com que suas aplicações são gerenciadas, podendo ser divididos em sistemas batch, de
tempo compartilhado e de tempo real, de acordo com a figura abaixo.
Sistemas
Multiprogramáveis/
Multitarefa
Sistemas BATCH
2.2.1
Sistemas de
Tempo Compartilhado
Sistemas de
Tempo Real
Sistemas BATCH
Foram os primeiros sistemas multiprogramáveis a serem implementados na década de 60.
Nesta modalidade, os programas eram submetidos para execução através de cartões perfurados
e armazenados em disco ou fita, para posterior execução. Vem daí o nome batch (lote de
cartões). O processamento em batch tem como característica não exigir interação do usuário
com o sistema ou com a aplicação. Todas as entradas ou saídas são implementadas por meio de
algum tipo de memória secundária, geralmente disco ou fita. Aplicações deste tipo eram
utilizadas em cálculo numérico, compilações, back-ups, etc.
6
Estes sistemas, se bem projetados, podem ser bastante eficientes devido à melhor
utilização do processador, mas podem oferecer tempos de resposta bastante longos.
Atualmente, os sistemas operacionais simulam este tipo de processamento, não havendo
sistemas dedicados a este tipo de execução.
2.2.2
Sistemas de Tempo Compartilhado
Também chamados sistemas de time-sharing, permitem que diversos programas sejam
executados a partir da divisão de tempo do processador em pequenos intervalos, denominados
fatia de tempo (ou time-slice). Caso a fatia de tempo não seja suficiente para a conclusão do
programa, este é interrompido pelo sistema operacional e substituído no processador por outro,
enquanto aguarda nova fatia de tempo. Neste tipo de processamento, cada usuário tem a
impressão de que a máquina está dedicada ao seu programa, como se ele fosse o único usuário
a se utilizar do sistema.
Geralmente permitem interação do usuário com a aplicação através de terminais
compostos por monitor, teclado e mouse. Estes sistemas possuem uma linguagem de controle
que permite ao usuário interagir com o sistema operacional através de comandos. Assim, é
possível verificar arquivos armazenados em disco ou cancelar execução de programas.
Normalmente, o sistema responde em apenas alguns segundos à maioria destes comandos, o
que se levou a chamá-los também de sistemas on-line.
A maioria das aplicações comerciais atualmente é processada em ambiente de tempo
compartilhado, que oferece tempos baixos de respostas a seus usuários e menores custos, em
função do alto grau de compartilhamento dos diversos recursos do sistema.
2.2.3
Sistemas de Tempo Real
Este tipo de sistema é implementado de forma bastante semelhante ao de tempo
compartilhado. O que caracteriza a diferença entre eles é o tempo exigido no processamento
das aplicações.
Enquanto nos sistemas de tempo compartilhado o tempo de processamento pode variar
sem comprometer as aplicações em execução, nos sistemas de tempo real os tempos de
execução devem estar dentro de limites rígidos, que devem ser obedecidos, caso contrário
poderão ocorrer problemas irreparáveis.
No sistema de tempo real não existe a idéia de fatia de tempo como nos sistemas de
tempo compartilhado. Um programa ocupa o processador o tempo que for necessário ou até
que apareça um outro com um nível de prioridade maior. Esta prioridade de execução é definida
pela própria aplicação e não pelo sistema operacional, como nos sistemas de tempo
compartilhado.
7
Estes sistemas são utilizados em aplicações de controle de processos, como
monitoramento de refinarias de petróleo, controle de tráfego aéreo, de usinas, ou em qualquer
aplicação onde o tempo de processamento é fator fundamental.
2.3
Sistemas com Múltiplos Processadores
Os sistemas com múltiplos processadores caracterizam-se por possuir duas ou mais CPUs
interligadas e trabalhando em conjunto. A vantagem deste tipo de sistema é permitir que
vários programas sejam executados ao mesmo tempo ou que um mesmo programa seja
subdividido em várias partes para serem executadas simultaneamente em mais de um
processador.
Esta técnica permitiu a criação de sistemas computacionais voltados para processamento
científico, prospecção de petróleo, simulações, processamento de imagens e CAD.
Um fator chave no desenvolvimento dos sistemas multiprocessados é a forma de
comunicação entre as CPUs e o grau de compartilhamento da memória e dos dispositivos de
E/S. Em função destes fatores, podemos classificar os sistemas multiprocessados de acordo com
a figura a seguir:
Sistemas
com
Múltiplos
Processadores
Sistemas
Fortemente
Acoplados
Simétricos
Sistemas
Fracamente
Acoplados
Assimétricos
Redes
Distribuídos
Tipos de Sistemas com Múltiplos Processadores
Na figura podemos perceber a divisão dos sistemas multiprocessados em duas categorias
iniciais: sistemas fortemente acoplados e fracamente acoplados. A grande diferença entre
estas duas categorias é que nos sistemas fortemente acoplados existe apenas uma memória
8
a ser compartilhada pelos processadores do conjunto, enquanto que nos fracamente
acoplados cada sistema tem sua própria memória individual. A taxa de transferência entre
processadores e memória em sistemas fortemente acoplados é muito maior que nos
fracamente acoplados.
Nos sistemas fortemente acoplados a memória principal e os dispositivos de E/S são
gerenciados por um único sistema operacional. Quando todos os processadores na
arquitetura são iguais, diz-se que o sistema é simétrico. No entanto, quando os
processadores são diferentes, dá-se à arquitetura a denominação assimétrica.
Nos sistemas fracamente acoplados, como os processadores estão em arquiteturas
diferentes, somente interligados por cabos de interconexão, cada CPU constitui uma máquina
independente, com memória própria, dispositivos de E/S e sistemas operacionais
independentes.
Nesta subdivisão, temos como exemplo as redes e os sistemas distribuídos.
No ambiente de rede, existem dois ou mais sistemas independentes (hosts), interligados
por linhas telefônicas, que oferecem algum tipo de serviço aos demais, permitindo que um
host compartilhe seus recursos, como impressora e diretórios, com os outros hosts da rede.
Enquanto nos sistemas em rede os usuários têm conhecimento dos hosts e seus serviços,
nos sistemas distribuídos os sistema operacional esconde os detalhes dos hosts individuais e
passa a tratá-los como um conjunto único, como se fosse um sistema só, fortemente
acoplado. Os sistemas distribuídos permitem, por exemplo, que uma aplicação seja dividida
em partes e que cada parte seja executada por hosts diferentes na rede. Para os usuários e
suas aplicações é como se não existisse a rede, mas um único sistema centralizado.
Outros exemplos de sistemas distribuídos são os clusters. Em um cluster podem existir
dois ou mais servidores ligados por algum tipo de conexão de alto desempenho, e o usuário
não conhece os nomes dos membros do cluster e nem quantos são. Quando é necessário
algum serviço, basta solicitar ao cluster para obtê-lo, sem se preocupar com quem vai dispor
e oferecer tal serviço. Clusters são muito utilizados em servidores de bancos de dados e
Web.
9
3. Sistemas Multiprogramáveis
Um Sistema Operacional pode ser visto como um conjunto de rotinas que executam
concorrentemente de forma ordenada. A possibilidade de um processador executar instruções
em paralelo com operações de entrada e saída permite que diversas tarefas sejam executadas
concorrentemente. É este conceito de concorrência o princípio fundamental para o projeto e
implementação de sistemas multiprogramáveis.
Os sistemas multiprogramáveis surgiram a partir das limitações dos sistemas
monoprogramáveis onde os recursos computacionais como processador, memória e dispositivos
de E/S eram utilizados de maneira muito pouco eficiente, limitando seu desempenho, com
muitos destes recursos permanecendo ociosos por longos períodos de tempo.
Nos sistemas monoprogramáveis somente um programa pode estar em execução de cada
vez, permanecendo o processador dedicado exclusivamente a uma tarefa, ficando ocioso
enquanto uma operação de leitura em disco é realizada. O tempo de espera é relativamente
longo, já que as operações de E/S são muito lentas se comparadas à velocidade de operação do
processador.
Outro aspecto a ser considerado é a sub-utilização da memória principal, onde um programa
nem sempre ocupa todo o espaço disponível, ficando o restante inutilizado. Nos sistemas
multiprogramáveis vários programas podem ser alocados na memória, concorrendo pelo uso do
processador. Dessa forma, quando um programa solicita uma operação de E/S, outros
programas poderão utilizar o processador, deixando a CPU menos ociosa e tornando o uso da
memória mais eficiente, pois existem vários residentes e se revezando na utilização do
processador.
A utilização concorrente da CPU deve ser feita de maneira que, quando um programa perde
o uso do processador e depois retorna para continuar sua execução, seu estado deve ser
idêntico ao do momento em que foi interrompido. O programa deverá continuar sua execução
exatamente na instrução seguinte àquela onde havia parado, aparentando ao usuário que nada
aconteceu. Em sistemas de tempo compartilhado existe a impressão de que o computador está
inteiramente dedicado ao usuário, ficando esse mecanismo totalmente transparente aos
usuários.
Quanto ao uso dos periféricos, é comum nos sistemas monoprogramáveis é comum termos,
por exemplo, impressoras paradas por um grande período de tempo e discos com acesso
restrito a um único usuário. Esses problemas são minimizados nos sistemas multiprogramáveis,
onde é possível compartilhar os dispositivos de E/S, como impressoras e discos, entre diversos
usuários e aplicativos.
10
3.1
Interrupção e Exceção
Durante a execução de um programa, alguns eventos inesperados podem ocorrer,
ocasionando um desvio forçado no seu fluxo normal de execução. Esses eventos são conhecidos
como interrupção ou exceção, e podem ser resultado de sinalizações de algum dispositivo de
hardware externo ao ambiente memória/processador. A diferença entre interrupção e exceção é
dada pelo tipo de evento ocorrido, embora alguns autores e fabricantes não façam tal distinção.
A interrupção é o mecanismo que permitiu a implementação da concorrência nos
computadores, sendo o fundamento básico dos sistemas multiprogramáveis/multitarefa.
Uma interrupção é sempre gerada por um evento externo ao programa e, sendo assim,
independe da instrução que está sendo executada. Um exemplo de interrupção é quando um
dispositivo avisa ao processador que alguma operação de E/S está completa. Neste caso, o
processador deve interromper o programa para tratar o término da operação.
Ao término de cada instrução a Unidade de Controle (situada dentro do processador)
verifica a ocorrência de algum tipo de interrupção. Desta forma, o programa em execução é
interrompido e seu controle é desviado para uma rotina do sistema responsável por tratar o
evento ocorrido, denominada rotina de tratamento de interrupção. Para que o programa
interrompido possa retornar posteriormente à sua execução é necessário que, no momento da
interrupção, um certo conjunto de informações sobre sua execução seja preservado.
Essas informações consistem basicamente no conteúdo dos registradores internos da
CPU, que deverão ser restaurados para a continuação do programa.
Programa
Salva
Contexto
Identifica
a origem
Interrupção
Trata a
Interrupção
Rotina
de
Restaura
Contexto
Tratamento
Mecanismo de interrupção/exceção
11
Para cada tipo de interrupção existe uma rotina de tratamento associada, para onde o
fluxo do programa é desviado. A identificação do tipo de evento ocorrido é fundamental para
determinar o endereço da rotina adequada ao tratamento da interrupção.
As interrupções podem ser geradas:
- Pelo programa do usuário (entrada de dados pela console ou teclado)
- Pelo hardware (operações de E/S)
- Pelo sistema operacional (ao término da fatia de tempo do processador destinada ao
programa)
As interrupções sempre são tratadas pelo Sistema Operacional.
A exceção é um evento semelhante à interrupção, pois também de fato interrompe um
programa.
A principal diferença é que a exceção é o resultado da execução de uma instrução dentro
do próprio programa, como a divisão por zero ou a ocorrência de um overflow (estouro de
capacidade de um campo) numa operação aritmética.
Na maioria das vezes, a exceção provoca um erro fatal no sistema, causando o término
anormal do programa. Isto se deve ao fato de que a exceção é melhor tratada dentro do
próprio programa, com instruções escritas pelo programador.
3.2
Buffer
A técnica de buffering consiste nua utilização de uma área em memória principal,
denominada buffer, criada e mantida pelo Sistema Operacional, com a finalidade de auxiliar
a transferência de dados entre dispositivos de E/S e a memória. O buffer permite minimizar a
disparidade de velocidade entre o processador e os dispositivos de E/S, e tem como objetivo
principal manter tanto os dispositivos de E/S como o processador ocupados a maior parte do
tempo.
A unidade de transferência do mecanismo de buffering é o registro. O buffer deve
permitir o armazenamento de vários registros, de forma que o processador tenha à sua
disposição dados suficientes para processar sem ter que interromper o programa a cada
leitura/gravação no dispositivo de E/S. Enquanto o processador está ocupado processando,
os dispositivos de E/S estão efetuando operações para outros processos.
3.3
SPOOL
A técnica de spooling foi criada inicialmente para auxiliar a submissão de processos ao
sistema, sendo os processos gravados em fita para posterior leitura e execução.
12
Com o aparecimento dos terminais para acesso ao sistema, esta técnica teve sua função
adaptada para armazenar o resultado da impressão dos programas em execução.
Isto é conseguido através da criação e manutenção, pelo Sistema Operacional de uma
grande área em disco, com a finalidade de simular uma impressora. Desta forma, todos os
usuários e seus programas imprimem, na verdade, para este arquivo em disco, liberando a
associação dos dispositivos de impressão diretamente aos programas que estão executando.
O usuário consegue visualizar o resultado de seus programas na tela dos terminais,
gerando assim mais eficiência e economia de papel e fita de impressão. À proporção que vão
sendo gerados no SPOOL, os relatórios vão sendo liberados para impressão pelo operador do
sistema, de forma ordenada e seqüencial. Para cada usuário, é como se ele tivesse uma
impressora associada para si.
3.4
Reentrância
É comum, em sistemas multiprogramáveis, vários usuários utilizarem os mesmos
aplicativos simultaneamente, como editores de texto, compiladores e outros utilitários. Nesta
situação, se cada usuário que utilizasse um destes aplicativos trouxesse o código executável
para a memória, haveria então diversas cópias de um mesmo programa ocupando espaço na
memória, o que causaria um grande desperdício de espaço.
Reentrância é a capacidade de um código executável (código reentrante) ser
compartilhado por vários usuários, exigindo apenas uma cópia do programa em memória. A
reentrância permite que cada usuário esteja executando um trecho diferente do código
reentrante, manipulando dados próprios, exclusivos de cada usuário.
Normalmente códigos reentrantes são utilizados em utilitários do sistema, como editores,
compiladores e linkers, promovendo um uso mais eficiente da memória e um desempenho
maior do sistema. Alguns sistemas operacionais permitem a possibilidade de se implementar
o conceito de reentrância em aplicações desenvolvidas pelo próprio usuário, mas não é
comum.
3.5
Segurança e Proteção do Sistema
A eficiência proporcionada por um ambiente multiprogramável implica em maior
complexidade do sistema operacional, já que alguns problemas de proteção surgem como
decorrência deste tipo de implementação.
Considerando-se que diversos usuários estão compartilhando os mesmos recursos,
como memória, processador e dispositivos de E/S, faz-se então necessário existir
mecanismos de proteção para garantir a confiabilidade e a integridade dos dados e
programas dos usuários, além do próprio sistema operacional.
13
Como vários programas ocupam a memória principal simultaneamente, cada usuário
possui uma área reservada onde seus programas e dados são armazenados durante o
processamento. O sistema operacional deve possuir mecanismos de proteção a essas áreas,
de forma a preservar as informações nela contidas. Caso um programa tente acessar uma
posição de memória fora de sua área, um erro indicando a violação de acesso deve ocorrer,
sendo responsabilidade do sistema operacional o controle eficiente do compartilhamento dos
recursos e a sincronização da comunicação, evitando problemas de consistência.
Semelhante ao compartilhamento da memória, um disco também armazena arquivos
de diferentes usuários. Novamente o sistema operacional deve garantir a integridade e
confiabilidade dos dados de cada usuário.
Todo o controle da segurança do sistema é implementado pelo sistema operacional, a
partir de mecanismos como grupos de usuários, perfis de usuários e direitos de acesso.
A proteção começa geralmente no procedimento de login, quando o usuário faz a
conexão inicial ao sistema, através de nome do usuário e senha. A partir daí, toda uma
estrutura de controle é iniciada, em função da identificação do usuário, no sentido de
proteger as áreas alocadas em memória, em disco, e até mesmo o uso do processador.
A proteção e segurança do sistema pode ser implementada também a nível do
programa do usuário, com a inserção de rotinas específicas dentro do programa para
controlar o acesso de usuários ao aplicativo, além de controlar internamente quais telas e
funções tal usuário pode acessar.
3.6
Operações de Entrada e Saída
Nos primeiros sistemas computacionais, a comunicação entre o processador e os
periféricos era direta, sendo o processador responsável por efetuar as operações de
leitura/gravação nos dispositivos.
O surgimento do controlador de E/S permitiu ao processador agir de maneira
independente dos dispositivos de E/S. Com esse novo elemento, o processador não mais se
comunicava diretamente com os periféricos, mas sim via controlador.
Passou a existir então três maneiras básicas de se implementar operações de E/S:
-
por programa: o processador sincronizava-se com o periférico e iniciava a
transferência de dados, ficando permanentemente testando o estado do periférico
para saber quando a operação chegaria ao seu final. O processador ficava ocupado
até o término da operação de E/S.
14
-
por interrupção: evoluindo o processo anterior, após o início da transferência de
dados o processador passou a ficar livre para realizar outras tarefas. Assim, em
determinados intervalos de tempo o sistema operacional deveria testar o estado dos
periféricos para saber se a operação de E/S tinha terminado. Este tipo de operação
permitiu um certo grau de paralelismo, já que um programa poderia ser processado
enquanto uma operação de leitura/gravação em periférico estava sendo efetuada.
Isto permitiu a implementação dos primeiros sistemas multiprogramáveis.
Memória
Principal
CPU
Controlador
Dispositivos de E/S
-
A necessidade de se transmitir cada vez um volume maior de informações trouxe
uma evolução significativa nas operações de E/S. Em vez de o processador ser
interrompido várias vezes para interrogar os dispositivos para saber do resultado das
operações, o que diminuía sua eficiência devido ao excesso de interrupções, foi
criado um dispositivo de transferência de dados chamado de DMA – Direct Memory
Access. Esta técnica permite que um bloco de dados seja transferido entre a
memória e os dispositivos de E/S sem a intervenção do processador, a não ser no
início (quando a operação é solicitada) e no final da transferência (quando o
processador é notificado sobre o término da operação). Na figura a seguir, podemos
ver a implementação do canal de E/S gerenciando vários controladores e, ligados a
estes, vários periféricos.
15
O canal de E/S funciona então como uma interface entre os controladores e a CPU,
como mostra a figura a seguir:
Memória
Principal
CPU
Canal de E/S
Controlador
Dispositivos de E/S
Controlador
Dispositivos de E/S
16
4. Estrutura do Sistema Operacional
4.1
Estrutura do Sistema
USUÁRIO
UTILITÁRIOS
NÚCLEO
DO SISTEMA
HARDWARE
Hierarquia do Sistema Operacional
O sistema operacional é formado por um conjunto de rotinas que oferecem serviços
essenciais aos usuários, às suas aplicações, e também ao próprio sistema. A esse conjunto
de rotinas dá-se o nome de núcleo do sistema ou kernel.
É fundamental não se confundir o núcleo do sistema com aplicações, utilitários ou o
interpretador de comandos, que acompanham o sistema operacional. As aplicações são
utilizadas pelos usuários de maneira transparente, escondendo todos os detalhes da
interação com o sistema. Os utilitários, como os compiladores, editores de texto e
interpretadores de comandos permitem aos usuários, desenvolvedores e administradores de
sistema uma interação amigável com o sistema.
Existe uma grande dificuldade em compreender a estrutura e o funcionamento do sistema
operacional, pois ele não é executado como uma aplicação tipicamente seqüencial, com
início, meio e fim. Os procedimentos do sistema são executados concorrentemente sem uma
ordem específica ou predefinida, com base em eventos dissociados do tempo. Muitos desses
eventos estão relacionados ao hardware e a tarefas internas do próprio sistema operacional.
17
4.2
Funções do Sistema
As principais funções do núcleo encontradas na maioria dos sistemas comerciais são as
seguintes:
-
Tratamento de interrupções e exceções: já explicados anteriormente, em detalhes;
-
Criação e eliminação de processos: função responsável por alocar em memória todos os
recursos necessários à execução do processo. É esta função que aloca em memória, além
do executável, o contexto do processo, o buffer de leitura/gravação (se necessário), além
de listas e estruturas de controle utilizadas pelo sistema operacional. Nesta função
também são estabelecidos vínculos físicos a arquivos em disco, fitas e outros periféricos
que serão usados no processamento. Quando do fim da execução do programa, é esta
função que desaloca todos os espaços em memória ocupados pelo processo, liberando-os
para futuras alocações a outros processos;
-
Escalonamento e controle de processos: função responsável por organizar a fila de
acesso ao processador. Utiliza parâmetros do sistema e do perfil do usuário para
estabelecer a ordem em que os processos permanecerão à espera pela liberação da CPU,
para então entrarem em execução;
-
Gerência de memória: função responsável por fornecer à função de criação/eliminação de
processos os endereços em memória disponíveis para alocação;
-
Gerência de sistemas de arquivos: responsável pelo gerenciamento dos arquivos, bem
como seu compartilhamento pelos diversos usuários, implementando mecanismos de
controle da segurança e direitos de acesso às áreas utilizadas pelos usuários nos diversos
dispositivos;
-
Gerência de dispositivos de E/S: responsável por gerenciar os dispositivos, prestando
auxílio à criação/eliminação de processos e á gerência de sistemas de arquivos no que diz
respeito ao endereçamento e associação de arquivos em periféricos;
-
Suporte a redes e teleprocessamento: é esta função que executa todos os serviços de
rede, fazendo o empacotamento das mensagens vindas dos terminais para a CPU central
e vice-versa, além de controlar e confirmar o envio e recebimento de todas as mensagens
que trafegam pela rede;
-
Contabilização de uso do sistema: responsável por contabilizar o uso de todos os
recursos do sistema consumidos pelos usuários e suas aplicações. São registrados: tempo
de CPU, tempo corrido, quantidade de área alocada em memória, em disco, linhas
impressas, páginas de papel, entre outros. Isto se faz necessário para servir de subsídio
para análise de performance, estatísticas de gastos com material de consumo e também
para definição de custos de processamento.;
18
-
Auditoria e segurança do sistema: função extremamente importante, pois detecta e
registra (num arquivo especial de LOG) todas as ocorrências de erro e violação de direitos
de acesso ao sistema, aos arquivos, à memória e a todos os recursos do sistema. O
arquivo de LOG é usado pela gerência de sistemas, com o intuito de verificar e
aperfeiçoar os mecanismos de segurança e proteção ao sistema.
A estrutura do sistema, a maneira como ele é organizado e o inter-relacionamento entre
seus diversos componentes pode variar conforme a concepção do projeto do sistema.
4.3
System Calls
Uma grande preocupação no projeto de sistemas operacionais se refere à implementação de
mecanismos de proteção ao núcleo do sistema e também o controle de acesso aos serviços
oferecidos pelo sistema. Caso uma aplicação que tenha acesso ao núcleo realize alguma
operação que altere sua integridade, todo o sistema poderá ficar comprometido e inoperante.
As system calls podem ser entendidas como uma porta de entrada para acesso ao núcleo do
sistema e aos seus serviços. Sempre que um usuário ou uma aplicação necessita de algum
serviço do sistema, é realizada uma chamada a uma de suas rotinas através de uma system call.
Através dos parâmetros fornecidos na system call, a solicitação é processada e uma
resposta é enviada à aplicação juntamente com um estado de conclusão indicando o sucesso ou
não da operação. Para cada serviço disponível existe uma system call associada, e cada sistema
operacional possui seu próprio conjunto de chamadas, com nomes, parâmetros e formas de
ativação específicos. Isto explica por que uma aplicação desenvolvida utilizando serviços de um
determinado sistema operacional não pode ser diretamente portada para um outro sistema.
Aplicação
System Call
Biblioteca
Núcleo do
Sistema
Operacional
Hardware
19
4.4
Modos de Acesso
Existem certas instruções que não podem ser colocadas diretamente à disposição das
aplicações, pois a sua utilização indevida poderia ocasionar sérios problemas à integridade do
sistema. Imagine que uma aplicação atualize um arquivo em disco. O programa, por si só, não
pode especificar diretamente as instruções que acessam seus dados no disco pois, como o disco
é um recurso compartilhado, sua utilização deve ser gerenciada unicamente pelo sistema
operacional. Tal procedimento evita que a aplicação possa ter acesso a qualquer área do disco
indiscriminadamente, o que poderia comprometer a segurança e a integridade do sistema de
arquivos.
Assim, fica claro que existem certas instruções que só podem ser executadas pelo sistema
operacional ou sob sua supervisão. As instruções que têm o poder de comprometer o sistema
são chamadas de instruções privilegiadas, enquanto as instruções que não comprometem o
funcionamento do sistema chamam-se instruções não-privilegiadas.
Para que uma aplicação possa executar uma instrução privilegiada, é preciso que haja um
mecanismo de proteção no processador, chamado modos de acesso. Existem basicamente dois
modos de acesso ao processador: modo usuário e modo kernel. Quando o processador trabalha
no modo usuário, somente instruções não-privilegiadas podem ser executadas, tendo assim
acesso a um número limitado de instruções do processador. Já no modo kernel (ou supervisor),
a aplicação pode ter acesso ao conjunto total de instruções do processador.
A melhor maneira de controlar o acesso às instruções privilegiadas é permitir que apenas o
sistema operacional tenha acesso a elas. Sempre que uma aplicação necessita executar uma
instrução privilegiada, a solicitação deve ser feita através de uma system call, que altera o modo
de acesso ao processador do modo usuário para o modo kernel. Ao término da execução da
rotina do sistema, o modo de acesso retorna para o modo usuário.
20
4.5
-
Arquiteturas: Sistemas monolíticos, em camadas e microkernel
Arquitetura monolítica: é caracterizada por possuir seus módulos compilados
separadamente mas linkados formando um único e enorme programa executável. Onde
os módulos podem interagir livremente. Os primeiros sistemas operacionais foram
desenvolvidos com base nesta arquitetura, o que tornava seu desenvolvimento e,
principalmente, sua manutenção muito difíceis. Como vantagens desta arquitetura
podemos citar a rapidez de execução e simplicidade de implementação. Como
desvantagens, a limitação quanto a inovações futuras e a dificuldade de manutenção.
Aplicação
Aplicação
Modo Usuário
Modo Kernel
System call
Núcleo
do
Sistema
Hardware
Arquitetura monolítica
21
-
Arquitetura em camadas: com o aumento do tamanho do código dos sistemas
operacionais, técnicas de programação estruturada e modular foram incorporadas em seu
projeto.Na arquitetura em camadas, o sistema é dividido em níveis sobrepostos. Cada
camada oferece um conjunto de funções que podem ser utilizadas somente pelas
camadas superiores. Neste tipo de implementação as camadas mais internas são mais
privilegiadas que as camadas mais externas. A vantagem da estruturação em camadas é
o isolamento das funções do sistema, facilitando sua manutenção. Uma desvantagem é o
desempenho, comprometido devido às várias mudanças de estado do processador
provocado pela mudança de camadas. A figura a seguir mostra esta arquitetura.
Camada Usuário
Camada Supervisor
Camada Executivo
Kernel
Arquitetura em camadas
-
Arquitetura microkernel (cliente x servidor): uma tendência nos sistemas operacionais
modernos é tornar o núcleo do sistema o menor e o mais simples possível. Para
implementar esta idéia, os serviços do sistema são disponibilizados através de processos,
onde cada um é responsável por oferecer um conjunto específico de funções, como
gerência de arquivos, gerência de processos, gerência de memória e escalonamento.
Sempre que uma aplicação deseja algum serviço, é realizada uma solicitação ao processo
responsável. Neste caso, a aplicação que está solicitando o serviço é chamada de cliente,
enquanto o processo que responde à solicitação é chamado de servidor. Um cliente, que
pode ser uma aplicação do usuário ou um outro componente do sistema operacional,
solicita um serviço enviando uma mensagem para o servidor. O servidor responde ao
cliente através de uma outra mensagem. A principal função do núcleo é realizar a
comunicação, ou seja, a troca de mensagens entre o cliente e o servidor. A utilização
22
deste modelo permite que os servidores operem em modo usuário, não tendo acesso
direto a certos componentes do sistema. Apenas o núcleo do sistema, responsável pela
comunicação entre clientes e servidores, executa em modo kernel. Como conseqüência,
se ocorrer um erro em algum servidor,este poderá parar, mas o sistema não ficará
inteiramente comprometido, aumentando assim a sua disponibilidade. Como os
servidores se comunicam através de trocas de mensagens, não importa se os clientes e
servidores processam em um sistema com um único processador, com vários
processadores ou ainda em um ambiente de sistema distribuído. A arquitetura
microkernel permite isolar as funções do sistema operacional por diversos servidores
pequenos e dedicados a serviços específicos, tornando o núcleo menor, mais fácil de
depurar (procurar e solucionar erros) e, com isso, aumentando a sua confiabilidade.
Apesar de todas as vantagens deste modelo, sua implementação é muito difícil. A
começar pelo desempenho, comprometido devido às várias trocas de modo de acesso a
cada troca de mensagens entre cliente e servidor. Outro problema é que certas funções
do sistema operacional, como operações de E/S, exigem acesso direto ao hardware.
Assim, o núcleo do sistema, além de promover a comunicação entre clientes e servidores,
passa a incorpora funções críticas do sistema, como escalonamento, tratamento de
interrupções e gerência de dispositivos.
Servidor
Servidor
Rede
Servidor
Memória
Arquivo
Servidor
Impressão
Servidor
Processo
Modo Usuário
Modo Kernel
Microkernel
Hardware
23
5. PROCESSO
O conceito de processo é a base para a implementação de um sistema multiprogramável. O
processador é projetado apenas para executar instruções, não sendo capaz de distinguir qual
programa se encontra em execução.A gerência de um ambiente multiprogramável é função
exclusiva do sistema operacional, que deve controlar a execução dos diversos programas e o
uso concorrente do processador.
A gerência do processador é uma das principais funções de um sistema operacional. Através
dos processos, um programa pode alocar recursos, compartilhar dados e trocar informações.
5.1
Componentes do processo
Um processo pode ser entendido inicialmente como um programa em execução, que tem
suas informações mantidas pelo sistema operacional.
Num sistema multiusuário, cada usuário tem a impressão de possuir o processador e todos
os demais recursos reservados exclusivamente para si, mas isto não é verdade. Todos os
recursos estão sendo compartilhados, inclusive a CPU. Neste caso, o processador executa o
processo do usuário por um intervalo de tempo e, no instante seguinte, poderá estar
processando um outro programa, do mesmo ou de outro usuário.
Para que a troca de processos possa ser feita sem problemas, é necessário que todas as
informações do programa que está sendo interrompido sejam guardadas, para que ele possa
retornar à CPU exatamente do ponto em que parou, não lhe faltando nenhuma informação vital
à sua continuação. Todas as informações necessárias à execução de um programa fazem parte
do processo.
Um processo também pode ser definido como o ambiente onde o programa é executado.
Este ambiente, além das informações sobre a execução, possui também a quantidade de
recursos do sistema que o programa pode utilizar,como espaço de endereçamento, tempo do
processador e área em disco.
Um processo é formado por três partes: contexto de software, contexto de hardware e
espaço de endereçamento, que juntas mantêm todas as informações necessárias à execução de
um programa.
24
Estrutura do processo:
Contexto de
Software
________
________
________
Programa
Contexto de
Hardware
Espaço de
endereçamento
•
Contexto de Software: neste contexto são especificadas características e limites
dos recursos que podem ser alocados pelo processo, como número máximo de arquivos
abertos, prioridade de execução, número máximo de linhas impressas, etc. Muitas destas
características são criadas no momento da criação do processo, quando da sua alocação.
O sistema operacional obtém, a partir do cadastro de usuários e do cadastro de
contas no sistema, as informações e características que valerão para o processo.
O contexto de software é composto por tr?es grupos de informações:
-
Identificação: neste grupo são guardadas informações sobre o usuário que criou o
processo, e, em função disso, suas áreas de atuação no sistema.
-
Quotas: são os limites de recursos do sistema que um processo pode alocar, como
área utilizada em disco, em memória, limite de linhas impressas, número máximo
de arquivos abertos, número máximo de operações de E/S pendentes, tempo
limite de CPU, etc.
-
Privilégios: diz respeito principalmente às prioridades assumidas pelo processo
durante sua execução.
•
Contexto de Hardware: armazena o conteúdo dos registradores gerais da
CPU, além dos registradores de uso específico. Quando um processo está em execução, o
seu contexto de hardware está armazenado nos registradores da CPU. No momento em
que o processo perde a utilização da CPU, o sistema salva as informações no contexto de
hardware do processo.
A troca de um processo por outro no processador, comandada pelo sistema
operacional, é denominada troca de contexto, que consiste em salvar o conteúdo dos
registradores do processo que está deixando a CPU e carrega-los com os valores
25
referentes ao do novo processo que irá executar. Essa operação resume-se em substituir
o contexto de hardware de um processo pelo de outro.
•
Espaço de endereçamento: é a área de memória pertencente a um processo onde
as instruções e os dados do programa são armazenados para execução. Cada processo
possui seu próprio espaço de endereçamento, que deve ser devidamente protegido do
acesso dos demais processos. Os contextos de software e de hardware não fazem parte
do espaço de endereçamento .
•
Bloco de controle do processo: é a estrutura de dados que compõe o processo,
contendo os contextos de software e de hardware e o espaço de endereçamento. O BCP
reside em memória, numa área reservada ao sistema operacional.
5.2
Estados do processo
Num sistema multiprogramável, um processo não deve alocar a CPU com exclusividade,
de forma que possa existir um compartilhamento no uso do processador. Os processos
passam por diferentes estados ao longo do processamento, em função de eventos gerados
pelo sistema operacional, pelo hardware, ou pelo próprio programa. São estados possíveis de
um processo:
-
Criação: neste estado o processo está sendo alocado na memória, sendo criado no
sistema. Todos os recursos necessários à execução do processo são reservados
durante a passagem do processo por este estado, o que acontece uma única vez.
Vários processos podem estar neste estado, ao mesmo tempo.
-
Pronto: é o estado onde os processos, depois de criados ou quando retornam do
tratamento de uma interrupção, permanecem aguardando a liberação da CPU para
que possam iniciar ou continuar seu processamento. É como se fosse uma fila,
gerenciada pelo sistema operacional, que se incumbe de organizar os processos de
acordo com as informações contidas no contexto de software (identificação,
quotas e privilégios). Vários processos podem estar neste estado, ao mesmo
tempo.
-
Execução: é onde o processo efetivamente utiliza a CPU. Ele permanece no
processador até que seja interrompido ou termine sua execução. Neste estado,
somente um processo pode permanecer de cada vez, já que existe apenas um
processador.
-
Espera: neste estado estão todos os processos que sofreram algum tipo de
interrupção de E/S, onde permanecem até que a intervenção seja resolvida. Vários
processos podem estar neste estado, ao mesmo tempo.
26
5.3
Saída: é o estado final do processo, quando este termina seu processamento.
Vários processos podem estar neste estado, ao mesmo tempo.
Mudanças de estado do processo
Um processo muda de estado diversas vezes durante sua permanência no sistema,
devido aos eventos ocorridos durante sua execução. São mudanças possíveis:
-
Criação Pronto: o processo foi criado, tem seus recursos alocados, e está apto a
disputar o uso da CPU.
-
Pronto  Execução: o processo é o primeiro da fila de pronto e a CPU fica
disponível. Neste momento o processo passa a ocupar a CPU, permanecendo em
execução até que seja interrompido ou termine sua execução.
-
Execução  Pronto: o processo foi interrompido por fatia de tempo ou por
prioridade. Ainda precisa de mais tempo na CPU para terminar sua execução, não
tem nenhuma intervenção pendente, por isso volta à fila de pronto para disputar
novamente o uso da CPU.
-
Execução  Espera: esta transição acontece quando o processo foi interrompido
por E/S. Significa que deve permanecer no estado de espera até que a interrupção
seja tratada pelo sistema. Neste estado o processo fica impedido de disputar o uso
da CPU.
-
Espera  Pronto: Após o término do tratamento da interrupção, o processo volta à
fila de pronto para disputar novamente o uso da CPU.
-
Execução  Saída: o processo terminou, e não mais disputará o uso da CPU.
A seguir, a figura mostra as mudanças possíveis de estado de um processo.
Pronto
Execução
Mudanças de estado de um
processo
27
5.4
Tipos de processos
Além dos processos do usuário, a CPU também executa processos do sistema. São aqueles
que oferecem os serviços do sistema operacional aos usuários, como criação/eliminação de
processos, tratamento de interrupção e todos aqueles correspondentes às funções do sistema já
estudadas. Estes executam sempre, com certa prioridade, concorrendo com os processos do
usuário.
Os processos em execução, do usuário, podem assumir dois tipos diferentes, de acordo com
suas características de uso de CPU e periféricos:
Processo CPU-bound: é aquele processo que utiliza muito a CPU. Ele ganha
uma fatia de tempo e a utiliza por inteiro, sem desperdiçar nenhum tempo. É o caso de
programas científicos, de cálculo numérico, estatística, matemática, e também na área de
simulação. Normalmente fazem pouca ou nenhuma entrada de dados, e muito
processamento.
Processo I/O-bound: é o tipo de processo que utiliza muito mais E/S do que
CPU. Aplicações em Banco de Dados, onde se faz consultas e atualizações constantes em
arquivos em disco são um bom exemplo deste tipo de processo. De acordo com essas
características, podemos dizer que este tipo de processo permanece mais tempo em
espera (tratando interrupções) do que propriamente em execução, ocupando a CPU por
períodos mínimos de tempo.
28
6. Gerência do Processador
6.1
Funções
Com o surgimento dos sistemas multiprogramáveis, onde múltiplos processos poderiam
permanecer na memória e disputar o uso de um único processador, a gerência do processador
tornou-se uma das atividades mais importantes em um sistema operacional.
A partir do momento em que vários processos podem estar no estado de pronto, devem
ser estabelecidos critérios para definir qual processo será escolhido para fazer uso do
processador. Tais critérios compõem a política de escalonamento, que é a base da gerência do
processador e da multiprogramação em um sistema operacional.
Dentre as funções da gerência do processador, podemos citar: manter o processador
ocupado a maior parte do tempo. balancear o uso da CPU entre processos, privilegiar a
execução de aplicações críticas, maximizar o throughput e oferecer tempos de resposta
razoáveis aos usuários interativos.
Cada sistema operacional possui sua política de escalonamento adequada ao seu
propósito e às suas características. Sistemas de tempo compartilhado, por exemplo, possuem
requisitos de escalonamento distintos dos sistemas de tempo real.
6.2
Critérios de escalonamento
-
Utilização do processador: corresponde a uma taxa de utilização, que na maioria dos
sistemas varia entre 30 e 90%. Uma utilização abaixo dos 30% indicaria um sistema
ocioso, com carga de processamento baixa, enquanto uma taxa de utilização acima dos
90% pode indicar um sistema bastante carregado, próximo da sua capacidade máxima
(em alguns casos tal situação pode levar a um crash – travamento do sistema).
-
Throughput: é o número de processos executados em um determinado intervalo de
tempo. Quanto maior o throughput, maior o número de tarefas executadas em função do
tempo. A maximização do throughput é desejada na maioria dos sistemas.
-
Tempo de Processador: é o tempo que um processo leva no estado de execução,
durante seu processamento. As políticas de escalonamento não interferem neste
parâmetro, sendo este tempo função apenas do código executável e da entrada/saída de
dados.
-
Tempo de Espera (pela CPU): é todo o tempo que o processo permanece na fila de
pronto, aguardando a liberação da CPU para ser executado. A redução deste tempo de
espera é desejada pela maioria das políticas de escalonamento.
29
-
Tempo de Turnaround: é o tempo total que o processo permaneceu no sistema, desde
sua criação até o momento em que é encerrado. São contados os tempos de alocação
de memória, espera na fila de pronto e interrupção (E/S).
-
Tempo de Resposta: é o tempo decorrido entre uma requisição ao sistema e o instante
em que a resposta começa a ser exibida. Em sistemas interativos, como aplicações online ou acesso à Web, os tempos de resposta devem ser da ordem de apenas poucos
segundos.
6.3
Escalonamentos Não-Preemptivos e Preemptivos
Escalonamentos do tipo não-preemptivos são aqueles onde o sistema operacional não
pode interromper o processo em execução para retirá-lo da CPU. Assim sendo, se nenhum
evento externo ocorresse durante a execução do processo, este permanecia na CPU até
terminar ou então alguma instrução do próprio programa o desviasse para o estado de espera
(operação de E/S).
Já os escalonamentos preemptivos são caracterizados pela possibilidade de o sistema
operacional interromper o processo em execução para retirá-lo da CPU e dar lugar a outro.
Neste caso o processo retirado da CPU volta ao estado de pronto, onde permanece
aguardando nova oportunidade de ocupar a CPU. Com o uso da preempção, é possível ao
sistema priorizar a execução de processos, como no caso de aplicações em tempo real. Outro
benefício é a possibilidade de implementar políticas de escalonamento que compartilhem o
processador de uma maneira mais uniforme, balanceando o uso da CPU entre os processos.
São escalonamentos não-preemptivos:
-
FIFO: o processo que chegar primeiro à fila de pronto é selecionado para execução, e
permanece utilizando o processador até terminar sua execução ou ser interrompido por
E/S. Neste caso, o próximo processo da fila de pronto é selecionado para execução.
Todo processo que chega à fila de pronto entra no final desta fila, conservando a ordem
de chegada na fila, até ser escalonado novamente. Apesar de simples, este
escalonamento apresenta algumas deficiências, principalmente no que diz respeito à
dificuldade de se prever o início da execução de um processo, já que a ordem de
chegada á fila de pronto deve ser observada à risca. Outro problema é quanto aos tipos
de processo, onde os CPU-bound levam vantagem no uso do processador em relação
aos do tipo I/O-bound, pois o sistema não trata este tipo de diferença. O escalonamento
FIFO foi inicialmente implementado em sistemas monoprogramáveis, sendo ineficiente
se aplicado em sistemas interativos de tempo compartilhado.
30
Abaixo, um exemplo de escalonamento utilizando o método FIFO: a ordem de chegada
dos processos (A, B, C) na fila de pronto foi obedecida, e, não tendo sido interrompidos por
E/S, os processos executaram inteiramente até terminar, de acordo com seus tempos
necessários para execução.
0
10
Processo A
10 u.t.
-
18
Processo B
8 u.t.
27
Processo C
9 u.t.
SJF (Shortest Job First): este escalonamento seleciona o processo que tiver o menor
tempo de processador ainda por executar. Desta forma, o processo que estiver na fila de
pronto com menor necessidade de tempo de CPU para terminar o seu processamento
será o escolhido para ocupar a CPU. Funciona com um parâmetro passado ao sistema
via contexto de software, onde o tempo estimado para o processo é informado
baseando-se em estatísticas de execuções anteriores.
Como exemplo, vamos utilizar os mesmos processos executados no
escalonamento FIFO acima, com seus respectivos tempos de execução em u.t.
(unidades de tempo): processo A com 10 u.t., processo B com 8 u.t, e o processo C com
9 u.t. Como neste escalonamento o que importa é o tempo de execução, a nova ordem
de escalonamento para utilização da CPU será B, C e A, como segue:
0
8
Processo B Processo C
-
17
27
Processo A
Cooperativo: este escalonamento busca aumentar o grau de concorrência no
processador. Neste caso, um processo em execução pode voluntariamente liberar o
processador retornando à fila de pronto, possibilitando que um novo processo seja
escalonado, permitindo melhor distribuição do tempo do processador. A liberação da
CPU é uma tarefa exclusiva do programa em execução, que de maneira cooperativa
libera o processador para um outro processo. Neste mecanismo, o processo em
execução verifica periodicamente uma fila de mensagens para saber se existem outros
processos na fila de pronto. Porém, como a interrupção do processo não depende do
sistema operacional, situações indesejáveis podem ocorrer, como por exemplo, se um
programa em execução não verificar a fila de mensagens, os demais programas não
terão chance de executar enquanto a CPU não for liberada. As primeiras versões do
Windows chegaram a utilizar este tipo de escalonamento.
31
São escalonamentos preemptivos:
Circular: é um tipo de escalonamento projetado especialmente para sistemas em tempo
compartilhado. É muito semelhante ao FIFO (obedece a ordem de chegada á fila de
PRONTO), mas quando um processo passa para o estado de execução há um limite de
tempo para o uso contínuo do processador, chamado fatia de tempo (time-slice) ou
quantum. Assim, toda vez que um processo é selecionado para execução uma nova fatia
de tempo lhe é concedida. Caso esta fatia de tempo expire, o sistema operacional
interrompe o processo, salva seu contexto e o direciona para a fila de PRONTO. Este
mecanismo é conhecido como preempção por tempo. A principal vantagem deste
escalonamento é não permitir que um processo monopolize a CPU. Outrossim, uma
desvantagem é que os processos CPU-bound são beneficiados no uso do processador
em relação aos processos I/O-bound, pois tendem a utilizar totalmente a fatia de tempo
recebida. A figura a seguir mostra o escalonamento circular com 3 processos, onde a
fatia de tempo é igual a 2 u.t. No exemplo não estão sendo levados em consideração
tempos de troca de contexto entre os processos, nem o tempo perdido em operações de
E/S. Os processos A, B e C, gastam 10 u.t, 6 u.t e 3 u.t., respectivamente.
-
A
B
C
2
-
4
6
8
10 11
17
u.t.
Por Prioridades: funciona com base num valor associado a cada processo, denominado
prioridade de execução. O processo com maior prioridade na fila de PRONTO é sempre
o escolhido para ocupar o processador, sendo os processos com prioridades iguais
escalonados pelo critério FIFO. Neste escalonamento o conceito da fatia de tempo não
existe. Como conseqüência disto, um processo em execução não pode sofrer preempção
por tempo. Neste escalonamento a perda do uso do processador somente ocorrerá no
caso de uma mudança voluntária para o estado de espera (interrupção por E/S), ou
quando um outro processo de prioridade maior passa (ou chega) para o estado de
pronto. Neste caso o sistema operacional interrompe o processo em execução, salva seu
contexto e o coloca na fila de pronto, dando lugar na CPU ao processo prioritário. Este
mecanismo é chamado de preempção por prioridade. A figura a seguir mostra a
execução dos processos A, B e C, com tempos de execução de 10, 4 e 3 u.t.
respectivamente, e valores de prioridades de 2, 1 e 3, também respectivamente. Na
32
maioria dos sistemas, valores menores correspondem à MAIOR prioridade. Assim, a
ordem de execução será invertida para B, A e C.
A
B
C
4
14
17
u.t.
A prioridade de execução faz parte do contexto de software do processo, e pode ser
estática (quando não pode ser alterada durante a existência do processo) ou dinâmica
(quando pode ser alterada durante a existência do processo). Este escalonamento é
muito usado em sistemas de tempo real, com aplicações de controle de processos,
controle de tráfego (sinais de trânsito, de trens/metrô, aéreo), robótica, entre outros.
-
Escalonamento Circular com Prioridades: implementa o conceito de fatia de tempo e de
prioridade de execução associada a cada processo. Neste escalonamento, um processo
permanece no estado de execução até que termine seu processamento, ou
voluntariamente passe para o estado de espera (interrupção por E/S), ou sofra uma
preempção por tempo ou prioridade. A principal vantagem deste escalonamento é
permitir um melhor balanceamento no uso do processador, com a possibilidade de
diferenciar o grau de importância dos processos através da prioridade (o Windows utiliza
este escalonamento).
-
Por Múltiplas Filas: Este escalonamento implementa várias filas de pronto, cada uma
com prioridade específica. Os processos são associados às filas de acordo com
características próprias, como importância da aplicação, tipo de processamento ou área
de memória necessária. Assim, não é o processo que detém a prioridade, mas sim a fila.
O processo em execução sofre preempção caso um outro processo entre em uma fila de
maior prioridade. O sistema operacional só pode escalonar processos de uma fila
quando todas as outras filas de maior prioridade estejam vazias. Os processos sempre
voltam para a mesma fila de onde saíram.
-
Por Múltiplas Filas com Realimentação: semelhante ao anterior, porém permitindo ao
processo voltar para uma outra fila de maior ou menor prioridade, de acordo com seu
comportamento durante o processamento. O sistema operacional identifica
dinamicamente o comportamento de cada processo e o redireciona para a fila mais
conveniente ao longo de seu processamento. É um algoritmo generalista, podendo ser
implementado na maioria dos sistemas operacionais.
7. Gerência de Memória / Memória Virtual
33
7.1
Introdução
Historicamente, a memória principal sempre foi vista como um recurso escasso e caro.
Uma das maiores preocupações dos projetistas foi desenvolver sistemas operacionais que não
ocupassem muito espaço de memória e, ao mesmo tempo, otimizassem a utilização dos
recursos computacionais. Mesmo atualmente, com a redução do custo e o aumento considerável
da capacidade da memória principal, seu gerenciamento é dos fatores mais importantes no
projeto e implementação dos sistemas operacionais.
Enquanto nos sistemas monoprogramáveis a gerência de memória não é muito complexa,
nos sistemas multiprogramáveis essa gerência se torna crítica, devido à necessidade de se
maximizar o número de usuários e aplicações utilizando eficientemente o espaço da memória
principal.
7.2
Funções
Geralmente, os programas são armazenados em memórias secundárias, de uso
permanente e não voláteis, como discos ou fitas. Como o processador somente executa o que
está na memória principal, o sistema operacional deve sempre transferir programas da memória
secundária para a principal antes de serem executados.Como o tempo de acesso às memórias
secundárias é muito superior ao tempo de acesso à memória principal, o sistema operacional
deve buscar reduzir o número de operações de E/S (acessos à memória secundária) a fim de
não comprometer o desempenho do sistema.
A gerência de memória deve tentar manter na memória principal o maior número de
processos residentes, permitindo maximizar o compartilhamento do processador e demais
recursos computacionais. Mesmo não havendo espaço livre, o sistema deve permitir que novos
processos sejam aceitos e executados. Outra preocupação na gerência de memória é permitir a
execução de programas maiores do que a memória física disponível.
Em um ambiente de multiprogramação o sistema operacional deve proteger as áreas de
memória ocupadas por cada processo, além da área onde reside o próprio sistema. Caso um
programa tente realizar algum acesso indevido à memória, o sistema deve, de alguma forma,
impedir o acesso.
7.3
Alocação Contígua Simples
Este tipo de alocação foi implementado nos primeiros sistemas operacionais, embora
ainda nos dias de hoje esteja presente em alguns sistemas monoprogramáveis. Nesse modelo, a
memória principal é dividida em duas partes, uma para o sistema operacional e a outra para o
programa do usuário. Dessa forma, o programador deve desenvolver suas aplicações
preocupado apenas em não ultrapassar o espaço de memória disponível.
34
Neste esquema o usuário tem total controle sobre toda a memória, exceto naquela área
onde reside o sistema operacional, cujo endereçamento é protegido por um registrador,
impedindo acesso indevido pelo usuário.
Sistema
Operacional
X
registrador
Área
para
programas
Proteção na alocação contígua simples
Apesar de simples implementação e código reduzido, a alocação contígua simples não
permite a utilização eficiente dos recursos do sistema, pois apenas um usuário pode dispor
destes recursos. Há inclusive um desperdício de espaço de memória, caso o programa não
venha a ocupar toda a área reservada para ele.
Sistema
Operacional
Programa do
Usuário
Área livre
Sub-utilização da memória principal
7.4
Segmentação de Programas
Na alocação contígua simples todos os programas estão limitados ao tamanho da
memória principal disponível para o usuário. Uma solução encontrada para o problema é dividir
o programa em módulos, de modo que seja possível a execução independente de cada módulo,
utilizando a mesma área de memória. A esta técnica dá-se o nome de segmentação ou overlay.
Consideremos um programa que tenha três módulos: um principal, um de cadastramento
e outro de impressão, sendo os módulos de cadastramento e impressão independentes. A
independência significa que quando um módulo estiver na memória para execução, o outro não
35
necessariamente precisa estar presente.O módulo principal é comum aos outros dois, logo,
precisa estar na memória durante todo o tempo da execução do programa.
Na figura a seguir, a memória é insuficiente para armazenar todo o programa, que
totaliza 9 KB. A técnica de overlay utiliza uma área de memória comum para armazenar o
módulo principal do programa e uma outra área na mesma memória, chamada área de overlay,
que será compartilhada entre os módulos de cadastramento e impressão. Assim, sempre que
um dos módulos for referenciado no módulo principal, o sistema o carregará da memória
secundária para a área de overlay, sobrepondo o módulo antigo na memória.
Memória Principal
2 KB
3 KB
4 KB
1 KB
Sistema
Operacional
Cadastramento
Módulo
Principal
Área de
Overlay
4 KB
Impressão
Área livre
2 KB
2 KB
Técnica de Overlay
A definição das áreas de overlay é função do programador, através de comandos
específicos da linguagem de programação utilizada.
A grande vantagem da utilização desta técnica consiste em se poder executar programas
maiores do que a memória física disponível.
7.5
Alocação Particionada Estática
Os sistemas operacionais evoluíram no sentido de proporcionar melhor aproveitamento
dos recursos disponíveis. Nos sistemas monoprogramáveis o processador permanece grande
parte do tempo ocioso e a memória principal é sub-utilizada. Os sistemas multiprogramáveis já
são muito mais eficientes no uso do processador, necessitando que vários processos estejam na
memória principal ao mesmo tempo e que novas formas de gerência de memória sejam
implementadas.
36
Nos primeiros sistemas multiprogramáveis a memória era dividida em blocos de tamanho
fixo, chamados partições.O tamanho dessas partições, estabelecido em tempo de inicialização
do sistema, era definido em função do tamanho dos programas que executariam no
ambiente.Sempre que fosse necessária a alteração do tamanho de uma partição, o sistema
deveria ser inicializado novamente com uma nova configuração.
Sistema
Operacional
Partição 1
2 KB
Partição 2
5 KB
Partição 3
8 KB
Inicialmente, os programas só podiam ser carregados e executados em apenas uma
partição específica, mesmo que as outras estivessem disponíveis. Esta limitação se devia aos
compiladores e linkeditores, que geravam apenas código absoluto. No código absoluto, todas as
referências a endereços no programa são posições físicas na memória, ou seja, o programa só
poderia ser carregado a partir do endereço de memória especificado no seu próprio código. A
esse tipo de alocação de memória chamou-se alocação particionada estática absoluta.
Coma evolução dos compiladores, linkeditores, montadores e loaders, o código gerado
deixou de ser absoluto e passou a ser relocável . No código relocável, todas as referências a
endereços no programa são relativas ao início do código e não a endereços fixos na memória.
Desta forma, os programas puderam ser alocados em qualquer partição livre, independente do
endereço inicial e da partição para a qual o código foi criado. A esse tipo de alocação deu-se o
nome de alocação particionada estática relocável.
Tanto nos sistemas de alocação absoluta como nos de alocação relocável, os programas,
normalmente, não ocupam totalmente as partições onde são alocados, deixando algum espaço
livre dentro das partições. Este tipo de problema, decorrente do esquema de alocação fixa de
partições, é chamado fragmentação interna.
A figura a seguir mostra um gráfico representando o particionamento estático de uma
memória e sua fragmentação interna.
Memória Principal
Sistema
37
Operacional
Programa C
1 KB
Programa A
3 KB
Fragmentação
interna
Programa E
5 KB
Alocação particionada estática com fragmentação interna
7.6
Alocação Particionada Dinâmica
A alocação particionada estática deixou clara a necessidade de uma nova forma de
gerência de memória principal, onde o problema da fragmentação interna fosse reduzido e,
conseqüentemente, o grau de compartilhamento da memória aumentado.
Na alocação particionada dinâmica, foi eliminado o conceito de partições de tamanho fixo.
Nesse esquema, cada programa, ao ser carregado, utilizaria o espaço necessário à sua
execução, tornando esse espaço a sua partição. Assim, como os programas utilizam apenas o
espaço de que necessitam, no esquema de alocação particionada dinâmica o problema da
fragmentação interna deixa de existir.
Porém, com o término de alguns programas e o início de outros, passam a existir na
memória blocos cada vez menores na memória, não permitindo o ingresso de novos programas.
A este tipo de problema dá-se o nome de fragmentação externa.
Para resolver o problema da fragmentação externa, os fabricantes tentaram duas
soluções:
- reunião de todos os blocos livres adjacentes, formando uma grande área livre, que se
transforma em uma nova partição;
-
realocação de todas as partições ainda ocupadas para a parte inicial da memória,
eliminando os blocos livres entre elas, formando uma grande área livre no final da
memória, que podia ser distribuída entre os processos ainda por executar. A este tipo
de compactação de espaços livres foi dado o nome de alocação particionada dinâmica
com realocação.
38
Estas soluções ajudaram a diminuir os problemas da fragmentação (tanto interna como
externa), mas, devido á complexidade dos algoritmos, nem todos os sistemas operacionais
as utilizaram.
7.7
Estratégias de Alocação de Partição
Os sistemas operacionais implementam basicamente três estratégias para determinar em
qual área livre um programa será alocado para execução. Essas estratégias tentam evitar ou
diminuir o problema da fragmentação.
A melhor estratégia a ser adotada por um sistema depende de uma série de fatores,
sendo o mais importante o tamanho dos programas executados no ambiente.
Independentemente do algoritmo utilizado, o sistema possui uma lista das áreas livres,
com endereço e tamanho de cada área.
São estratégias de alocação:
-
Best-fit: é escolhida a melhor partição, ou seja, aquela que deixa o menor espaço sem
utilização. Uma grande desvantagem desta estratégia é que, como são alocados
primeiramente as partições menores, deixando pequenos blocos, a fragmentação
aparece mais rapidamente.
-
Worst-fit: aloca o programa na pior partição, ou seja, aquela que deixa o maior espaço
livre. Esta técnica, apesar de aproveitar primeiro as partições maiores, acaba deixando
espaços livres grandes o suficiente para que outros programas utilizem esses espaços,
permitindo que um número maior de processos se utilizem da memória, diminuindo
ou retardando a fragmentação.
-
First-fit: esta estratégia aloca o programa na primeira partição que o couber,
independente do espaço livre que vai deixar. Das três estratégias, esta é a mais
rápida, consumindo menos recursos do sistema.
7.8
Swapping
É uma técnica aplicada à gerência de memória que visa dar maior taxa de utilização à
memória principal, melhorando seu compartilhamento. Visa também resolver o problema da
falta de memória principal num sistema.
Toda vez que um programa precisa ser alocado para execução e não há espaço na
memória principal, o sistema operacional escolhe entre os processos alocados que não tem
previsão de utilizar a CPU nos próximos instantes (quase sempre entre aqueles que estão em
39
interrupção de E/S ou no final da fila de pronto), e “descarrega” este processo da memória para
uma área especial em disco, chamada arquivo de swap, onde o processo fica armazenado
temporariamente. Durante o tempo em que o processo fica em swap, o outro que necessitava
de memória entra em execução ocupando o espaço deixado pelo que saiu. Pouco antes de
chegar a vez do processo armazenado em swap utilizar a CPU, o sistema escolhe um outro
processo para descarregar para swap e devolve o anterior da área de swap para a memória
principal, para que este possa ser executado novamente. E vai trabalhando assim até que os
processos vão terminando. O problema dessa técnica é que pode provocar um número
excessivo de acesso à memória secundária (disco), levando o sistema a uma queda de
desempenho.
7.9
Memória Virtual
Anteriormente foram apresentadas diversas técnicas de gerenciamento de memória que
evoluíram no sentido de maximizar o número de processos residentes na memória principal e
reduzir o problema da fragmentação, porém os esquemas vistos se mostraram muitas vezes
ineficientes. Além disso, o tamanho dos programas e de suas estruturas de dados estava
limitado ao tamanho da memória disponível. Como vimos, a utilização da técnica de overlay para
contornar este problema é de difícil implementação na prática e nem sempre uma solução
garantida e eficiente.
Memória virtual é uma técnica sofisticada e poderosa de gerência de memória onde as
memórias principal e secundária são combinadas, dando ao usuário a impressão de que existe
muito mais memória do que a capacidade real de memória principal.
O conceito de memória virtual baseia-se em não vincular o endereçamento feito pelo
programa aos endereços físicos da memória principal. Desta forma, o programa e suas
estruturas de dados deixam de estar limitados ao tamanho da memória física disponível, pois
podem possuir endereços vinculados à memória secundária, que funciona como uma extensão
da memória principal.
Outra vantagem desta técnica é permitir um número maior de processos compartilhando
a memória principal, já que apenas partes de cada processo estarão residentes. Isto leva a uma
utilização mais eficiente do processador, além de minimizar (ou quase eliminar) o problema da
fragmentação.
A seguir, os conceitos que envolvem a gerência de memória virtual, incluindo a
paginação:
- espaço de endereçamento virtual: é o conjunto de endereços virtuais que um
processo pode endereçar.
-
Espaço de endereçamento real: analogamente, é o conjunto de endereços reais que
um processo pode endereçar.
40
-
Mapeamento: como o espaço de endereçamento virtual não tem nenhuma relação
com o espaço de endereçamento real, um programa pode fazer referência a um
endereço virtual que esteja fora dos limites da memória principal (real), ou seja, os
programas e suas estruturas de dados não estão mais limitados ao tamanho da
memória física disponível. Quando um programa é executado, apenas uma parte do
seu código fica residente na memória principal, permanecendo o restante na memória
virtual até o momento de ser referenciado. Este esquema de endereçamento virtual é
ignorado pelo programador no desenvolvimento das aplicações. Cabe ao compilador e
ao linkeditor gerar códigos executáveis em função do endereçamento virtual, e o
sistema operacional se incumbe de administrar os detalhes durante a sua execução. O
processador apenas executa instruções e referencia dados residentes no espaço de
endereçamento real. Portanto, deve existir um mecanismo que transforme os
endereços virtuais em endereços reais. Este mecanismo é o que chamamos de
mapeamento, e consiste em permitir a tradução do endereço virtual em endereço real.
Como conseqüência, um programa não mais precisa estar necessariamente em
endereços contíguos na memória real para ser executado.
-
Tabela de endereçamento de páginas: estrutura mantida pelo sistema para armazenar,
entre outras informações, o mapeamento. É única e exclusiva para cada processo,
relacionando os endereços virtuais do processo ás suas posições na memória real.
-
Memória virtual por paginação: é a técnica de gerência de memória onde o espaço de
endereçamento virtual e o espaço de endereçamento real são divididos em blocos do
mesmo tamanho chamados páginas. As páginas do espaço virtual são chamadas
páginas virtuais, enquanto as páginas do espaço real são chamadas páginas reais ou
frames.
-
Page fault: é a falha de página. Sempre que o processo referencia um endereço
virtual, o sistema verifica se a página correspondente já está carregada na memória
real. Se não estiver, acontece o page fault. Neste caso, o sistema deve transferir a
página virtual para um endereço na memória real. Esta transferência é chamada de
paginação. O número de page faults gerados por um processo em um determinado
intervalo de tempo é chamado de taxa de paginação do processo. Se esta taxa atingir
valores elevados, pode haver um comprometimento do desempenho do sistema. Um
page fault provoca uma interrupção no processo, pois há a necessidade de acessar
operações de E/S. Assim, sempre que acontece a paginação, uma interrupção de E/S
fará com que o processo em execução seja interrompido e colocado em estado de
espera até que sua intervenção de E/S seja realizada, quando então o processo
voltará à fila de pronto e entrará em execução de acordo com o escalonamento
normal. Enquanto o sistema trata a interrupção deste processo, um outro ocupará a
CPU.
41
-
Working-set: é o conjunto de páginas de um processo, em memória real, em um
determinado instante. Este conceito surgiu com o objetivo de reduzir o problema do
thrashing e está relacionado ao princípio da localidade. Existem dois tipos de
localidade que são observados durante a execução da maioria dos programas. A
localidade espacial é a tendência de que, após uma referência a um endereço de
memória, sejam realizadas novas referências a endereços próximos ou adjacentes. A
localidade espacial é a tendência de que, após a referência a uma posição de
memória, esta mesma posição seja referenciada novamente num curto intervalo de
tempo. A partir desse princípio de localidade, o processador tenderá a concentrar suas
referências a um conjunto de páginas do processo durante um determinado período
de tempo. Imagine um loop principal de um programa que ocupe três páginas. A
tendência é que estas três páginas tenham um alto índice de referências durante a
execução do programa.
-
Thrashing: é o efeito causado pelo excesso de page faults durante a execução de um
processo. Pode acontecer a nível de programa ou de sistema. A nível de programa,
pode ser provocado por um programa mal escrito, com desvios incondicionais
espalhados por seu código (desobedecendo portanto aos princípios da localidade), ou
por um limite de working-set muito pequeno (que não comporte o loop principal do
programa, por exemplo). A solução para estes casos é reescrever o programa ou
aumentar o limite do working-set. No caso de thrashing de sistema, significa que há
mais páginas sendo requeridas na memória real do que ela pode realmente suportar.
A solução é aumentar o tamanho da memória física.
-
Tamanho da página: deve estar entre 512 bytes e 128KB, aproximadamente. Páginas
menores promovem maior compartilhamento da memória, permitindo que mais
programas possam ser executados. Páginas maiores diminuem o grau de
compartilhamento da memória, com menos programas disputando o processador.
Assim conclui-se que quanto menor o tamanho da página, MAIOR é o grau de
compartilhamento da memória e da CPU.
-
Políticas de busca de páginas: definem como as páginas serão carregadas da memória
virtual para a memória real. A política por demanda estabelece que uma página
somente será carregada quando for referenciada. Este mecanismo é conveniente, pois
leva para a memória real somente as páginas realmente necessárias à execução do
programa, ficando as outras na memória virtual. A outra política, chamada paginação
antecipada, funciona carregando antecipadamente várias páginas da memória virtual
para a principal, na tentativa de economizar tempo de E/S. Nem sempre o sistema
acerta na antecipação, mas o índice de acertos é quase sempre maior que o de erros.
Políticas de alocação de páginas: determinam quantos frames cada processo pode
manter na memória real. A política de alocação fixa determina um limite de workingset igual para todos os processos, e pode ser vista como uma política injusta, na
medida em que processos maiores normalmente necessitam de um working-set maior.
A outra política é a variável, que define um limite de working-set diferente e variável
-
42
para cada processo, em função de seu tamanho, taxa de paginação ou até mesmo da
taxa de ocupação da memória principal.
-
Políticas de substituição de páginas: definem onde serão trocadas as páginas, quando
se fizer necessária uma substituição. Na política local, somente as páginas do
processo que gerou o page fault são candidatas a serem substituídas.Já na política
global, todas as páginas alocadas na memória principal são candidatas à substituição,
independente do processo que gerou o page fault. Como uma página de qualquer
processo pode ser escolhida, pode ser que este processo sofra um aumento
temporário da taxa de paginação em função da diminuição das suas páginas alocadas
em memória.
7.10 Algoritmos de substituição de páginas
O maior problema na gerência de memória virtual por paginação não é decidir quais
páginas carregar para a memória real, mas sim quais páginas liberar. Quando há a necessidade
de carregar uma página, o sistema deve selecionar entre as diversas páginas alocadas na
memória qual delas deverá ser liberada pelo processo.
Os algoritmos de substituição de páginas têm o objetivo de selecionar os frames que
tenham as menores chances de serem referenciados num futuro próximo. Caso contrário, o
frame poderia retornar diversas vezes para a memória real, provocando excesso de page faults.
São algoritmos de substituição de páginas:
-
algoritmo ótimo: impossível de ser implementado, pois o processador não consegue
prever com segurança qual frame não será mais referenciado durante a execução do
programa. Tal fato deve-se à lógica do programa e aos dados que ele manipula,
desconhecidos pelo processador.
-
Algoritmo aleatório: escolhe qualquer página, entre as alocadas na memória, para
fazer a substituição. Em função de sua baixa eficiência, este algoritmo não muito
utilizado, embora consuma poucos recursos do sistema.
-
Algoritmo FIFO (first in, first out): escolhe a página que está há mais tempo na
memória principal para fazer a troca. É um algoritmo de simples implementação, mas
corre o risco de retirar uma página que, embora tenha sido carregada há mais tempo,
esteja sendo muito utilizada. Por essa razão não é muito usado.
Algoritmo LFU (least frequently used): elege a página menos freqüentemente usada
para efetuar a troca. Através de um contador, armazenado na tabela de
endereçamento de páginas, mo sistema identifica quantas referências cada página
teve e utiliza esta informação para escolher a página.
-
43
-
Algoritmo LRU (least recently used): elege a página menos recentemente usada para
fazer a troca. O sistema mantém na tabela de endereçamento de páginas um campo
onde são armazenadas a data e a hora da última referência de cada página, e com
base nestas informações faz a seleção.
-
Algoritmo NRU (not recently used): elege a página menos recentemente usada para
efetuar a troca. O sistema exclui da decisão a página mais recente e escolhe entre as
outras, pelo método FIFO, qual página deve sair.
44
8. Gerência de Sistemas de Arquivos
8.1
Estrutura de Diretórios
É como o Sistema organiza logicamente os arquivos. Contém entradas associadas aos
arquivos, com as informações de localização, nome, organização e outros atributos:
•
Nível único: é a implementação mais simples de uma estrutura de diretórios, onde
existe um único diretório contendo todos os arquivos do disco. É muito limitado, não
permitindo a criação de arquivos com o mesmo nome.
•
Diretório pessoal: Evolução do modelo anterior, permite a cada usuário ter ser
“diretório” particular, sem a preocupação de conhecer os outros arquivos do disco. Neste
modelo há um diretório “master” que indexa todos os diretórios particulares dos usuários,
provendo o acesso a cada um.
•
Múltiplos níveis (ÁRVORE): É o modelo utilizado hoje em dia em quase todos os
Sistemas Operacionais. Nesta modalidade cada usuário pode criar vários níveis de
diretórios (ou sub-diretórios), sendo que cada diretório pode conter arquivos e subdiretórios. O número de níveis possíveis depende do Sistema Operacional.
8.2
Sistemas de alocação de arquivos
•
FAT: sistema criado no MS-DOS e depois utilizado no Windows. Usa listas
encadeadas, tem um limite de área utilizável em partições de 2 GB, caracteriza-se por um
baixo desempenho no acesso e armazenamento.
•
FAT32: igual ao FAT no que diz respeito a organização e desempenho, mas pode
trabalhar com partições de até 2TB.
•
NTFS: NT File System, original da plataforma Windows NT/2000/XP. Opera com
uma estrutura em árvore binária, oferecendo alto grau de segurança e desempenho:
-
•
nomes de arquivo com até 255 caracteres, podendo conter maiúsculas, minúsculas
e espaços em branco;
dispensa ferramentas de recuperação de erros;
bom sistema de proteção de arquivos;
criptografia;
suporta discos de até 264 bytes.
UNIX: Usa diretório hierárquico, com um raiz e outros diretórios subordinados.
Neste Sistema Operacional todos os arquivos são considerados apenas como uma
“seqüência” de bytes, sem significado para o Sistema. É responsabilidade da aplicação
45
controlar os métodos de acesso aos arquivos. O UNIX utiliza também alguns diretórios
padronizados, de exclusividade do Sistema.
8.3
Gerência de espaço livre
São três as formas de se implementar estruturas de espaços livres. Uma delas é através
de uma tabela denominada mapa de bits, onde cada entrada da tabela é associada a um bloco
do disco representado por um bit, que estando com valor 0 indica que o espaço está livre, e
com valor 1 representa um espaço ocupado. Gasta muita memória, pois para cada bloco do
disco há uma entrada na tabela.
A segunda forma é utilizando uma lista encadeada dos blocos livres do disco. Desse
modo, cada bloco possui uma área reservada para armazenar o endereço do próximo bloco
livre. Apresenta problemas de lentidão no acesso, devido às constantes buscas seqüenciais na
lista.
A terceira forma é a tabela de blocos livres. Nesta, leva em consideração que blocos
contíguos de dados geralmente são alocados/liberados simultaneamente. Desta forma, pode-se
enxergar o disco como um conjunto de segmentos de blocos livres. Assim, pode-se manter uma
tabela com o endereço do primeiro bloco de cada segmento e o número de blocos contíguos
que se seguem.
-
Alocação contígua: armazena o arquivo em blocos seqüencialmente dispostos no
disco. O arquivo é localizado através do endereço do primeiro bloco de sua
extensão em blocos. O principal problema neste tipo de alocação é a existência de
espaço livre para novos arquivos, que deve ser contígua. Utiliza as estratégias
best-fit, worst-fit e first-fit (já conhecidas) para definir onde o arquivo será
alocado. Causa alto índice de fragmentação no disco.
-
Alocação encadeada: nesta modalidade o arquivo é organizado como um conjunto
de blocos ligados logicamente no disco, independente de sua localização física,
onde cada bloco possui um ponteiro para o bloco seguinte. A fragmentação não
representa problemas na alocação encadeada, pois os blocos livres para alocação
do arquivo não necessariamente precisam estar contíguos. O que acontece é a
quebra do arquivo em vários pedaços, o que aumenta o tempo de acesso. Neste
tipo de alocação só se permite acesso seqüencial aos blocos do arquivo, sendo
esta uma das principais desvantagens da técnica. Outra desvantagem é a perda de
espaço nos blocos com o armazenamento dos ponteiros.
-
Alocação indexada: esta técnica soluciona a limitação da alocação encadeada, no
que diz respeito ao acesso, pois permite acesso direto aos blocos do arquivo. Isso
é conseguido mantendo-se os ponteiros de todos os blocos do arquivo em uma
única estrutura chamada bloco de índice. Este tipo de alocação, além de permitir
acesso direto aos blocos, não utiliza informações de controle nos blocos de dados.
46
8.4
Proteção de acesso
Considerando-se que os meios de armazenamento são compartilhados por vários
usuários, é fundamental que mecanismos de proteção sejam implementados para garantir a
integridade e proteção individual dos arquivos e diretórios:
-
Senha de acesso: mecanismo de simples implementação, mas apresenta duas
desvantagens: não é possível determinar quais os tipos de operação podem ser
efetuadas no arquivo, e, se este for compartilhado, todos os usuários que o
utilizam devem conhecer a senha de acesso.
-
Grupos de usuário: é muito utilizada em muitos Sistemas Operacionais. Consiste
em associar cada usuário a um grupo. Os grupos são organizados logicamente
com o objetivo de compartilhar arquivos e diretórios no disco. Este mecanismo
implementa três níveis de proteção: OWNER (dono), GROUP (grupo) e ALL
(todos). Na criação do arquivo o usuário especifica se o arquivo pode ser acessado
somente pelo seu criador, pelo grupo ou por todos os usuários, além de definir que
tipos de acesso podem ser realizados (leitura, escrita, execução e eliminação)
-
Lista de controle de acesso: é uma lista associada ao arquivo onde são
especificados quais os usuários e os tipos de acesso permitidos. O tamanho
dessa estrutura pode ser bastante extenso se considerarmos que um arquivo
pode ser compartilhado por vários usuários. Além deste problema, há o
inconveniente de se fazer acesso seqüencial à lista toda vez que um acesso é
solicitado. Em determinados sistemas de arquivos pode-se utilizar uma
combinação de proteção por grupos de usuários ou por listas de acesso,
oferecendo assim maior flexibilidade ao mecanismo de proteção de arquivos e
diretórios.
47
9. BIBLIOGRAFIA
Arquitetura de Sistemas Operacionais
Francis B. Machado
Ed. LTC
Sistemas Operacionais: Conceitos e Aplicações
Abraham Silberschatz
Ed. Campus
Sistemas Operacionais Modernos
A.S. Tanenbaum
Ed. Campus
48
Download