Sistemas Operacionais

Propaganda
OBS:
As informações aqui contidas foram extraídas, modificadas e/ou adaptadas de diversas
fontes bibliográficas, dentre as quais destacam-se Arquitetura de Sistemas Operacionais
(Francis B. Machado e Luiz Paulo Maia), Sistemas Operacionais (Deitel & Deitel) e
Sistemas Operacionais Modernos (A. Tanenbaum) e de vários sites com propósitos
educativos voltados para uma disciplina, dentro de um particular contexto educacional. O
propósito desse material é puramente educativo e NÃO se destina a qualquer tipo ou
forma de comércio e/ou fins promocionais de qualquer espécie.
[email protected]
1
Siglas
ENIAC
ENIAC – Fotos
005
006
007
1.0
1.1
1.2
1.3
1.4
Visão Geral
Recursos do Sistema Computacional
Compartilhamento de Recursos
Máquina de Níveis
Breve Histórico
011
012
013
013
014
2.0
2.1
2.1.1
2.1.2
2.1.2.1
2.1.2.2
2.1.2.3
2.2
2.2.1
2.2.2
2.2.3
2.2.4
2.2.5
Componentes de um Sistema Operacional
Tipos de Sistemas Operacionais
Sistema Monogramável/Monotarefa
Sistema Multiprogramável/Multitarefa
Sistemas em Lotes (Batches)
Sistemas de Tempo Compartilhado
Sistemas de Tempo Real : Críticos e Não Críticos
Sistemas com Múltiplos Processadores
Sistemas Fortemente Acoplados: Simétricos e Não Simétricos
Sistemas Fracamente Acoplados: de Rede e Distribuídos
Sistemas em Cluster
Sistemas Embarcados
Sistemas de Cartões Inteligentes
018
020
020
021
022
022
023
024
025
027
028
028
028
3.0
3.1
3.2
3.3
3.4
Arquitetura de Sistemas Operacionais
Sistema Monolítico
Sistema em Camadas
Sistema Micronúcleo (Microkernel)
Características de um Sistema Operacional
030
030
031
032
033
4.0
4.1
4.2
4.2.1
4.2.2
4.2.3
4.2.4
4.2.5
4.2.6
4.2.7
4.2.8
4.3
4.4
4.5
Concorrência
Interrupções
Operacões de Entrada e Saída (E/S)
E/S Controlada por Programa
Polling
E/S Controlada por Interrupção
DMA (Direct Memory Access)
Canal de E/S
Processador de E/S
Buffer
Spooling
Reentrância
Proteção ao Sistema
Modos de Execução
035
035
037
037
037
037
037
037
038
038
038
038
039
039
5.0
5.1
5.2
5.3
5.3.1
5.3.2
5.3.3
CPU – Unidade Central de Processamento
Registradores Visíveis
Registradores Invisíveis
CPU, Comunicação e Periféricos
Loop de Status
Interrupções
Via DMA
040
040
040
041
042
042
043
2
6.0
6.1
6.2
6.3
6.4
6.5
6.5.1
6.5.2
6.5.3
6.5.4
Processos
Componentes de Processo
Contexto de um Processo
Estados Básicos de um Processo
Mudanças de Estado
Tipos de Processos
Processo CPU Bound
Processo I/O Bound
Processo em Foreground
Processo em Background
045
045
045
048
050
050
050
050
051
051
7.0
7.1
7.2
7.2.1
7.2.2
7.2.3
7.2.4
7.3
7.3.1
7.3.2
7.3.3
7.3.4
7.3.5
7.3.6
7.3.7
7.3.8
7.3.9
7.4
7.5
Gerenciamento da CPU
Algoritmos de Escalonamento
Critérios de Escalonamento
Utilização da CPU
Eficiência
Tempo de Turnaround
Tempo de Resposta
Tipos de Escalonamento
Escalonamento FIFO
Escalonamento Shortest Job First (SJF)
Escalonamento Shortest Remaining Time (SRT)
Escalonamento Cooperativo
Escalonamento Circular (Round Robin)
Escalonamento por Prioridades
Escalonamento por Múltiplas Filas
Escalonamento por Múltiplas Filas com Realimentação
Escalonamento por Fração Justa (Fair Share)
Escalonamento em Sistemas de Tempo Real
Escalonamento com Múltiplos Processadores (CPUs)
052
053
054
054
054
054
054
054
054
055
055
056
056
057
058
058
059
059
061
8.0
8.1
8.2
8.3
8.4
8.5
8.6
8.7
8.8
8.9
8.10
8.10.1
8.10.2
8.10.3
8.10.4
8.10.5
8.10.6
Gerenciamento de Memória
Introdução
Funções
Alocação Contígua Simples
Segmentação de Programas
Alocação Particionada Estática
Alocação Particionada Dinâmica
Estratégias de Alocação de Partição
Swapping
Memória Virtual
Algoritmos de Substituição de Páginas
Algoritmo Ótimo
Algoritmo Aleatório
Algoritmo FIFO
Algoritmo LFU
Algoritmo LRU
Algoritmo NRU
062
062
062
062
063
064
066
066
067
068
070
070
070
070
070
071
071
3
9.0
9.1
9.1.1
9.1.2
9.1.3
9.2
9.2.1
9.2.2
9.2.3
9.3
9.4
Gerenciamento de Sistemas de Arquivos
Estrutura de Diretórios
Nìvel Único
Diretório Pessoal
Múltiplos Níveis
Sistemas de Alocação de Arquivos
FAT
FAT32
NTFS
Gerência de Espaço Livre
Proteção de Acesso
072
072
072
072
072
072
072
072
072
072
073
10.0
10.1
10.2
10.3
10.4
10.5
10.6
Exemplos de Sistemas Operacionais
DOS
UNIX
OS/2
Windows
Windows NT
Linux
075
075
076
077
077
079
081
11.0
Bibliografia
082
12.0
Dicionário de Termos (Glossário)
083
4
Siglas
ALU
ASCII
CDC
CISC
CPU
DEC
DMA
DRAM
ENIAC
EEPROM
EPROM
HD
IBM
I/O
IOP
IP
IRQ
E/S
LAN
MAN
PROM
RAM
RISC
ROM
SRAM
TCP
UCP
ULA
WAN
WWW
-
Aritmethic Logical Unit
American Standard Code for Information Interchange
Control Data Corporation
Complex Instruction Set Computer
Central Processing Unit
Digital Equipment Corporation
Direct Memory Acess
Dinamic RAM
Electronic Numerical Intregator and Computer
Electricaly Erasable Programmable Read Only Memory
Erasable Programmable Read Only Memory
Hard Disk
International Business Machines
Input and Output
Input and Output Processor
Internet Protocol
Interrupt Request
Entrada e Saída
Local Area Network
Metropolitan Area Network
Programmable Read Only Memory
Random Access Memory
Reduced Instruction Set Computer
Read Only Memory
Static RAM
Transport Control Protocol
Unidade Central de Processamento
Unidade Lógica Aritmética
Wide Area Network
Wide World Web
5
ENIAC (Electronic Numerical Intregator and Computer)
O 1º computador, o Harvard Mark I, foi projetado por Aiken, da universidade de Harvard em 1939 e
foi implementado com relés pela IBM em 1944 e , por isso mesmo não é considerado o primeiro
computador eletrônico do mundo.
O 1º computador eletrônico, o ENIAC (Electronic Numerical Intregator and Computer), teve seu
projeto iniciado em 1943, com a aplicação específica de efetuar os cálculos para a geração de tabelas
balísticas para tiros de canhões, tendo ficado operacional em 1946, ou seja, logo após o término da
2ª Grande Guerra Mundial. Ele pesava cerca de 30 toneladas e suas partes ocupavam várias salas do
prédio onde ele estava sendo construído. O computador media 5,50 m de altura e 25 m de
comprimento e ocupava 180 m² de área construída. Foi construído sobre estruturas metálicas com
2,75 m de altura e contava com 70 mil resistores e entre 17.468 e 18.000 válvulas a vácuo ocupando
a área de um ginásio desportivo.
Segundo Tom Forester, quando acionado pela primeira vez, o ENIAC consumiu tanta energia que as
luzes de Filadélfia piscaram várias vezes. As milhares de válvulas consumiam uma quantidade
enorme de eletricidade e dissipavam muito calor, sendo necessários vários aparelhos de ar
condicionado para refrigerá-lo. No ENIAC, a programação era efetuada por chaves e pela colocação
de vários fios em soquetes específicos (plugboard wiring). Esta máquina não tinha um sistema
operacional e seu funcionamento era parecido com uma calculadora simples de hoje. O ENIAC,
assim como uma calculadora, tinha de ser operado manualmente. A calculadora efetua os cálculos a
partir das teclas pressionadas, fazendo interação direta com o hardware.
No ENIAC era preciso conectar fios, relês e seqüências de chaves para que se determinasse a tarefa
a ser executada. À cada tarefa diferente o processo deveria ser refeito. A resposta era dada por uma
seqüencia de lâmpadas. Não era nada fácil mudar o programa e, através dessa experiência negativa,
evoluiu-se para o conceito de programa armazenado (stored program concept), cuja idéia foi
apresentada ainda em 1946 pelos pesquisadores Burks, Goldstine e Von Neumann, tendo este último
emprestado seu nome para o que conhecemos como a clássica “máquina tipo Von Neumann”.
Abaixo podem ser observadas algumas fotos de partes do ENIAC acessadas e obtidas em 18 de
Março de 2009, para fins didáticos e não comerciais, a partir dos links abaixo relacionados:
http://pt.wikipedia.org/wiki/ENIAC
;
http://www.google.com.br/imgres?imgurl=http://www.enciclopedia.com.pt/images/eniac.jpg&imgre
furl=http://www.enciclopedia.com.pt/articles.php%3Farticle_id%3D536&h=440&w=629&sz=160&
tbnid=FCp-056MiXZ8AM::&tbnh=96&tbnw=137&prev=/images%3Fq%3Deniac&hl=ptBR&usg=__yNVCmHPFVCJf_o6fnpQiCGnkHAs=&ei=J3HKSfzrOobpnQezzp2OAw&sa=X&oi=i
mage_result&resnum=4&ct=image&cd=1 ;
http://images.google.com.br/images?hl=ptBR&q=fotos+eniac&revid=932243387&ei=J3HKSfzrOobpnQezzp2OAw&resnum=0&um=1&ie=U
TF-&ei=FXLKSZvTH5LsnQeZt7SSAw&sa=X&oi=image_result_group&resnum=4&ct=title
6
7
http://news.cnet.com/Photos-ENIAC-in-the-works/2009-1006_3-6038088.html?tag=txt
8
http://news.cnet.com/Photos-ENIAC-in-the-works---page-2/2009-1006_3-6038088-2.html?tag=txt
9
http://news.cnet.com/Photos-ENIAC-in-the-works---page-4/2009-1006_3-6038088-4.html?tag=txt
http://news.cnet.com/Photos-ENIAC-in-the-works---page-8/2009-1006_3-6038088-8.html?tag=txt
10
SISTEMAS OPERACIONAIS
1.0 Visão Geral
Um sistema operacional pode ser entendido (ou “visto”) como um programa que atua como
intermediário entre um ou mais usuários e o hardware de um computador. O propósito básico de um
sistema operacional é propiciar um ambiente no qual os usuários possam executar programas de
forma conveniente e eficiente. Compreender as razões que estão por trás do desenvolvimento dos
sistemas operacionais nos dá uma melhor compreensao das tarefas que eles executam e da forma
como o fazem.
.
Um sistema operacional, em seu sentido mais amplo, deve ser capaz de garantir a operação correta
de um sistema computacional, partilhando os recursos disponíveis (memória, CPU e dispositivos de
E/S (entrada e saída) da melhor forma possível. Os serviços fornecidos, é claro, diferem de um
sistema operacional para outro, mas nosso objetivo é explorar classes comuns à maioria dos sistemas
operacionais (S.O.), não nos atendo à particularidades deste ou daquele.
Sistemas de computadores evoluíram dos primeiros que não continham nenhum sistema operacional
como o ENIAC, por exemplo, para máquinas de multiprogramação, e dessas para máquinas de
tempo compartilhado, e depois para computadores pessoais e, por fim, para sistemas
verdadeiramente distribudos. À medida que a demanda por novas características e melhor eficiencia
cresciam e o hardware mudava. os sistemas operacionais evoluíram para cumprir novos papéis.
Por mais complexo que possa parecer, um sistema operacional é apenas um conjunto de rotinas
sendo executadas “harmoniosamente” pela CPU (processador), da mesma forma que qualquer outro
programa. Sua principal função é gerenciar os diversos recursos existentes no sistema
computacional, i.e., memória, CPU, e dispositivos de entrada e saída (E/S).
Atualmente, o usuário pode interagir com os sistemas operacionais via comandos fornecidos
diretamente a este ou via operações do tipo “click” (click) ou “duplo-click” (double click), onde um
dispositivo de apontamento (pointing device) é utilizado para percorrer a tela no sentido vertical e
horizontal de forma a permitir ao usuário “apontar” para o aplicativo a ser executado.
No caso de comandos fornecidos via operações de “clicks”, torna-se necessária a existência de uma
interface gráfica com a qual o usuário possa interagir de forma fácil e intuitiva. As interfaces que
possuem essa propriedade recebem o nome de GUIs (Graphic User Interface) sendo normalmente
bastante amigáveis quanto à sua utilização, o que contribui em muito para o aumento da
produtividade dos usuários que dela fazem uso. As interações com os usuários normalmente se dá
via caixas de diálogos (dialog boxes) com botões e campos de texto, como mostrado abaixo.
11
No caso de comandos fornecidos pela linha de comando há um aplicativo denominado interpretador
de linha de comando, ou CLI (Command Line Interpreter) que é responsável pela validação da
sintaxe do comando, i.e., se a grafia do comando está correta assim como os eventuais parametros
passados juntamente com o comando como, por exemplo, nos comandos do DOS fornecidos abaixo,
onde alguns comandos são válidados e executados e outros, escritos erroneamente, são descartados.
A utilização de linhas de comando é bastante tediosa visto que exige do usuário o conhecimento dos
comandos, seus parametros e de suas respectivas sintaxes, porém é ainda bastante comum em
ambientes do tipo mainframe ou em plataformas do tipo UNIX,com seu Shell , seus comandos e sua
conhecida verbose.
O nome sistema operacional nao é unico para designar esse conjunto de programas. Nomes como
monitor, executivo, supervisor ou controlador possuem, normalmente, o mesmo significado. Um
sistema operacional possui inúmeras funções, mas para efeitos didáticos, resumiremos em apenas 2:
a facilidade de acesso aos recursos e o compartilhamento desses recursos de forma organizada.
1.1 Recursos do Sistema Computacional
Um sistema de computação possui, normalmente, diversos elementos que o constituem, tais como
unidades de disco, monitores (vídeos/terminais), impressoras, fitas etc. Quando um desses
dispositivos é utilizado, sobre a ótica/perspectiva do usuário, não há a preocupação sobre como essa
utilização será realizada, assim como os detalhes técnicos envolvidos.
Por exemplo, uma operação cotidiana como a leitura de um arquivo em disco ou disquete pode
parecer simples mas, na verdade, nessa operação “simples”, foi utilizado um grande conjunto de
rotinas especificas, todas elas controladas pelo sistema operacional, Foi o sistema operacional que
acionou a cabeça de leitura e gravação da unidade de disco, posicionou-a na trilha e setor onde estão
os dados, transferiu os dados do disco para a memória e, finalmente, comunicou ao aplicativo que
solicitou a operação que esta foi concluída com exito, entregando ao aplicativo solicitante os dados.
O exemplo acima ilustra como o sistema operacional age de interface entre os usuários e os recursos
disponíveis no sistema, tornando esta comunicação transparente e permitindo aos usuários um
trabalho mais eficiente e com menores chances de erros. Este conceito de ambiente simulado, criado
pelo sistema operacional, é denominado de máquina estendida/expandida ou máquina virtual
(virtual machine) e está presente, de alguma forma, na maioria dos sistemas atuais.
12
É comum ter-se a idéia que aplicativos tais como os compiladores, depuradores, linkers e outras
ferramentas fazem parte do sistema operacional, mas na verdade, esses aplicativos são apenas
utilitarios, destinados a ajudar a interação do usuário com o computador. Eles podem estar ou
não presentes em um sistema computacional qualquer, sem que o sistema operacional necessite
deles. Sob a ótica do sistema, esses aplicativos são apenas mais alguns processos que serão
executados.
1.2 Compartilhamento de Recursos
Em sistemas do tipo multiusuário, onde vários usuários podem estar compartilhando os mesmos
recursos, como, por exemplo, CPU, memória e periféricos, é necessário que todos tenham a
oportunidade de ter acesso a esses recursos, de forma tal que um usuário não venha a interferir no
trabalho do outro. Por exemplo, uma impressora que pode ser utilizada por vários usuários do
sistema, deverá possuir algum nível de controle para impedir que a impressao de um usuário
interrompa a impressão de outros. Novamente, o sistema operacional é responsável por permitir o
acesso concorrente à impressora e a outros recursos eventualmente disponíveis, de forma
organizada e protegida, dando ao usuario a impressao de ser o único a utilizá-los.
O compartilhamento de recursos permite, tambem, a diminuição drástica dos custos, na medida
em que mais de um usuário pode utilizar as mesmas facilidades concorrentemente, como discos,
impressoras, recursos de rede etc. Nao é somente em sistemas do tipo multiusuário que o sistema
operacional é importante. Em um computador pessoal do tipo desktop ou laptop é o sistema
operacional neles residente (Windows, Linux etc.) que permite a execução de várias tarefas, como
por exemplo, a impressão de um documento, uma sessão de conversação via web com imagens e
sons, a cópia de um arquivo pela Internet ou a execução de uma planilha eletrônica.
1.3 Máquina de Níveis
Um sistema computacional qualquer, visto somente como um ou mais gabinetes compostos de
circuitos eletrônicos, cabos, fios e fontes de alimentação (hardware), nao tem nenhuma utilidade.
É através da utilização dos programas (software) que o computador consegue armazenar dados
em discos, imprimir relatórios, gerar gráficos, realizar cálculos dentre tantas outras funções. O
hardware é o responsável final pela execução das instruções de um programa, com a finalidade
de se realizar alguma tarefa.
Uma operação efetuada pelo software pode ser implementada em hardware e, análogamente, uma
instrução executada pelo hardware pode ser simulada via software. Esta decisão fica a cargo dos
projetistas de computadores em função de aspectos tais como custo, confiabilidade e
desempenho. Tanto o hardware quanto o software são lógicamente equivalentes, interagindo de
uma forma única para o usuário. Nos primeiros computadores, a programação era realizada em
painéis, através de fios, plugs e cabos, exigindo um grande conhecimento do hardware e de sua
linguagem de máquina. Isso era uma grande dificuldade para os programadores da época. A
solução para esse problema foi o surgimento do sistema operacional, que tornou a interação entre
usuário e computador mais simples, confiável e eficiente. A partir desse acontecimento, nao
existia mais a necessidade de o programador se envolver com a complexidade do hardware para
poder trabalhar; ou seja, a parte física do computador tomou-se transparente para o usuário.
Partindo desse principio, podemos considerar o computador como uma máquina de niveis ou
camadas, onde inicialmente existem dois niveis: o nível 0 (hardware) e o nível 1 (sistema
operacional - software). Sendo assim, o usuário leigo pode ver a máquina como sendo apenas
constituída do sistema operacional, com quem realmente interage, como se o hardware não
existisse. Reforça-se aqui o conceito de que se dá à essa visão abstrata o nome de máquina
virtual ou máquina estendida/expandida já abordado anteriormente.
13
Um sistema computacional qualquer evidentemente não é constituído de apenas 2 níveis, mas de
quantos níveis forem necessários para que o usuário possa interagir com o hardware – essa é uma
abstração normalmente empregue do ponto de vista didático – sendo que o usuário não precisa
saber de em qual camada ele se encontra.
1.4 Breve Histórico
A evolução dos sistemas operacionais sempre esteve ligada à história da evolução do hardware. O
ENIAC não dispunha de um sistema operacional ou qualquer outro tipo de software tal como o
conhecemos atualmente. A programação era feita mediante a utilização de cabos elétricos
especiais que eram conectados em diferentes partes da máquina. Esse trabalho era executado por
pessoas capacitadas para fazê-lo, como por exemplo, cientistas e engenheiros, ou pessoas
especialmente treinadas por estes. Com o desenvolvimento do transistor e consequente
susbstituição das válvulas por estes novos componentes, a miniaturização teve início e, com ela, a
drástica diminuição do tamanho dos computadores.
Com o contínuo avanço da tecnologia, o conceito de Von Neumann, pode ser implementado em
uma máquina eletrônica, dando origem aos computadores programáveis e, juntamente com eles o
desenvolvimento dos primeiros programas para serem executados. À medida que os empresários
e os governos foram se apercebendo da enorme aplicabilidade dessas máquinas, mais e mais
aplicações foram sendo desenvolvidas até que foi sentida a necessidade de se ter um programa
maior e mais complexo capaz de coordenar todas essas diferentes tarefas de uma forma mais fácil
e coordenada do que aquela que vinha sendo executada. Dessa necessidade crescente nasceram os
primeiros sistemas operacionais, que foram sendo instalados nos grandes computadores
comerciais.
Os primeiros sistemas operacionais eram do tipo monousuário (monouser) e monotarefa
(monotask) e, com isso, as tarefas eram executadas de forma sequencial, i.e., uma após outra. As
tarefas podiam ser agrupadas e executadas em lotes (batches), cada lote pertencendo à uma
determinada empresa, que pagava os custos decorrentes do processamento. O conceito de
datacenters ,i.e., empresas especializadas em processar os dados de outras empresas, acabara de
nascer e já estava se desenvolvendo.
As crescentes necessidades comerciais fizeram com que um novo tipo de sistema operacional
fosse desenvolvido e entrasse nesse cenário. Nascia o conceito de sistema operacional do tipo
multitarefa (multi-task) que era capaz de executar e controlar várias tarefas simultaneamente,
tornando ainda maior a aplicabilidade dessas máquinas.
O próximo passo foi o desenvolvimento de sistemas operacionais do tipo multi-usuário (multiuser), onde vários usuários diferentes podiam utilizar o mesmo computador e seus diferentes
recursos. Além disso, cada usuário podia ter o seu próprio conjunto de tarefas sendo executadas.
Quanto mais recursos da máquina eram alocados por determinado usuário (e suas tarefas), maior
era o preço do processamento decorrente, fazendo com que somente grandes empresas e governos
pudessem pagar por esses serviços. O total da conta era de certa forma proporcional à quantidade
de recursos utilizados por aquele usuário (e suas tarefas). Itens como quantidade de memória,
tempo de CPU, espaço em disco e em fitas magnéticas etc., eram inicialmente calculados por
pessoas treinadas para esse serviço, porém com o passar do tempo, essa tarefa passou também a
ser executada por processos especificamente desenvolvidos para esse fim.
14
O ínicio da era dos grandes computadores, constituídos por dezenas de placas contendo milhares
de componentes eletrônicos e dispositivos de armazenamento de dados (discos e fitas magnéticas)
havia começado e ainda perdura até nos dias de hoje.
Somente no ínicio da década de 1980, com o desenvolvimento e amadurecimento do conceito de
circuitos integrados e, posteriormente, com o desenvolvimento da tecnologia que permitiu a sua
criação e disseminação, apareceram os primeiros computadores pessoais. Novamente a história
iria se repetir, só que desta vez na escala residencial e não mais na empresarial.
O primeiro sistema operacional, por assim dizer, voltado para os recém chegados PCs, foi o DOS
(Disk Operating System) desenvolvido em regime de parceira pela IBM e pela Microsoft. Não
tardou para que os novos usuários domésticos também passassem a demandar novos serviços e
com eles um novo sistema operacional, o MS-Windows.
As primeiras versões do MS-Windows não foram bem sucedidas comercialmente devido ao
excessivo processamento que este novo sistema demandava da CPU e que esta não conseguia
suprir adequadamente. Somente com uma nova linha de CPUs, mais rápidas e poderosas,
desenvolvida pela Intel é que o sistema Windows começou a ganhar mercado e a se impor como
padrão.
Exemplos de sistemas operacionais para máquinas de grande porte (mainframes) são o UNIX, o
Open VMS, o MPX-32, o Sun OS e o OS/370, dentre tantos outros. Atualmente, há várias
versões do UNIX, cada qual adaptada e desenvolvida por fabricantes diferentes, tais como o HPUX, o AIX (IBM), o SOLARIS (SUN) e o Tru-64 (DEC/HP).
Atualmente, há vários tipos de sistemas operacionais voltados para os PCs (desktops e laptops)
derivados do UNIX, como por exemplo o Linux, o Librix, o Xenix, o QNX, o Fedora, o Suse etc.
Plataformas mainframes de alto desempenho podem apresentar mais de uma CPU em sua
arquitetura, o que demanda sistemas operacionais ainda mais complexos, capazes de tirar proveito
do grande poder de processamento dessas CPUs.
Resumindo :
a) O sistema operacional separa as diversas aplicações sendo executadas em um computador
do hardware por elas acessado. Ele pode ser visto como uma camada de software (SW)
envolvendo o hardware (HW), de forma a tornar este último transparente ao usuário
comum.
b) Cabe ainda ao Sistema Operacional, primordialmente, gerenciar os diversos recursos
pertencentes não somente ao reino do hardware tais como processadores, memória,
dispositivos de entrada/saída; dispositivos de comunicação, mas também ao reino do
software tais como as mais diversas aplicações de software que o usuário utiliza.
c) Os sistemas operacionais passaram por diversas fases de evolução ao longo dessas 6
últimas décadas
15
A evolução dos Sistemas Operacionais, sempre em sincronia com a evolução de um hardware
cada mais melhor e mais rápido pode ser vista, década à década, abaixo :
Década de 1940 (utilizavam-se válvulas, plugs e relés)
 Os primeiros computadores não dispunham de sistemas operacionais.
Década de 1950 (utilizavam-se válvulas, plugs e relés)
 Executavam um serviço (job) por vez.
 Dispunham de tecnologias que facilitavam a transição de um job para outro.
 Eram chamados de sistemas de processamento em lote de fluxo único.
 Os programas e dados eram submetidos consecutivamente em uma fita magnética.
Década de 1960 (aparecimento dos transistores)
 Permanecem como sistemas de processamento em lote
 Processam vários serviços (jobs) simultaneamente
 Multiprogramação
 Um job podia usar o processador enquanto outros utilizavam os dispositivos
periféricos.
 Desenvolveram-se sistemas operacionais avançados para atender a diversos usuários
de forma interativa
 Esses sistemas foram desenvolvidos para apoiar usuários interativos simultâneos.
 O tempo de retorno foi reduzido a minutos ou segundos.
 Aparecem os primeiros sistemas de tempo real
 Fornecem respostas dentro de um prazo determinado.
 O tempo e os métodos de desenvolvimento foram aperfeiçoados.
 O MIT usou o sistema CTSS para desenvolver seu próprio sucessor, o Multics.
 Os sistemas TSS, Multics e CP/CMS, incorporavam memória virtual, endereçam mais
localizações de memória do que as realmente existentes.
Década de 1970 (apareceram os primeiros circuitos integrados)
 Os sistemas de tempo compartilhado eram primordialmente multimodais, isto é, suportavam
processamento em lote, tempo compartilhado e aplicações de tempo real.
 A computação pessoal estava apenas em seu estágio inicial, tendo sido favorecida por
desenvolvimentos anteriores à tecnologia de multiprocessadores.
 O Departamento de Defesa Americano patrocinou o desenvolvimento do TCP/IP, inicialmente
denominado de ARPANET (Advanced Research Projects Agency NETwork), que pretendia-se
ser utilizado como protocolo de comunicação padrão. Esse protocolo passou a ser amplamente
usado em ambientes militares e universitários, porém, apresentava alguns problemas de
segurança, dado que crescentes volumes de informação eram transmitidos por linhas vulneráveis.
Década de 1980 (apareceram os primeiros circuitos integrados de baixa escala)
 Foi a década do surgimento dos computadores pessoais e das estações de trabalho.
 A computação era distribuída aos locais em que era necessária, gerando demanda.
 Era relativamente fácil aprender a usar um computador pessoal.
 Apareceram as primeiras interfaces gráficas com o usuário (GUI)
 A transferência de informações entre computadores interconectados em rede tornou-se mais
econômica e prática.
 O modelo de computação cliente/servidor se disseminou e com isso, os clientes são os
próprios computadores que solicitam serviços variados e os servidores são os computadores que
executam os serviços solicitados.
 O campo da engenharia de software continuou a evoluir, recebendo grande impulso do
governo dos Estados Unidos, que visava controlar de modo mais rígido os projetos de software do
16
Departamento de Defesa. Uma das metas era a reutilização de códigos o que podia ser obtido pelo
maior grau de abstração nos idiomas de programação. Vários threads de instrução podiam ser
executados independentemente.
Década de 1990 (apareceram os primeiros circuitos integrados de larga escala)
 O desempenho do hardware melhorou exponencialmente, com uma crescente capacidade de
processamento e armazenamento cada vez mais acessível. A execução de programas grandes e
complexos passou a poder ser feita em computadores pessoais. Teve início o desenvolvimento
dos serviços extensivos aos banco de dados e processamento remoto. A computação distribuída
ganhou ímpeto e com isso, inúmeros computadores independentes podiam executar tarefas
comuns.
 O suporte a sistemas operacionais para tarefas de rede tornaram-se padrão, com grande
aumento da produtividade e comunicação.
 A Microsoft Corporation tornou-se dominante no mercado, com suas várias versões dos seus
sistemas operacionais Windows, que empregava vários conceitos usados nos primeiros sistemas
operacionais Macintosh e que permitia que os usários executassem várias aplicações concorrentes
com facilidade.
 A tecnologia de objeto tornou-se popular em várias áreas da computação, com diversas
aplicações sendo desenvolvidas em linguagens de programação orientadas a objetos, como por
exemplo, o C++ e o Java. Apareceram alguns sistemas operacionais orientados a objetos
(SOOO), onde os objetos representavam componentes do sistema operacional.
 A maioria dos softwares comerciais era vendida como código-objeto e o código-fonte não era
incluído, permitindo aos fabricantes que ocultassem informações e técnicas de programação
patenteadas.
 Os softwares gratuitos e de fonte aberto tornaram-se muito comuns na década de 1990. O
software de fonte aberto era distribuído com o código-fonte, permitindo que outras pessoas
examinassem e modificassem o software. O sistema operacional Linux e o servidor Web Apache
são ambos software de fonte aberto.
 Richard Stallman lançou o projeto GNU, que recriava e ampliava as ferramentas do sistema
operacional UNIX da AT&T. Stallman discordava do conceito de pagar licença para usar um
software.
Grande porte (mainframes)
1990
1950
1960
1º Sistema Operacional
Monoprogramável
Monotarefa
1970
Sistemas
Multitarefa
Introduzido o
conceito de
Memória Virtual
1980
Sistemas
Multiprogramáveis
Multitarefa
Microcomputadores
17
2.0 Componentes de um Sistema Operacional
Conforme já visto anteriormente, um usuário interage com o sistema operacional via uma ou mais
aplicações de usuário e, muitas vezes, por meio de uma aplicação especial denominada Shell ou
CLI, ou interpretador de comandos. A maioria dos interpretadores de comando atuais é
implementada como interfaces de texto que habilitam o usuário a emitir comandos por meio de
um tec1ado, ou como GUIs (Graphic User Interface) que permitem que o usuario 'aponte-eclique' e 'arraste-e-solte' ícones para requisitar serviços ao sistema operacional, como por
exemplo, para abrir uma aplicação como um editor de textos, um aplicativo para apresentações ou
mesmo uma planilha eletrônica.
O Microsoft Windows XP, por exemplo, fornece uma GUI por meio da qual os usuários podem
fornecer comandos. O usuário pode abrir alternativamente uma janela de comandos (Command
Prompt (antigo DOS)) que aceite os comandos fornecidos pelo usuário.
O software que contém os componentes centrais do sistema operacional chama-se núcleo do
sistema, ou kernel (em alemão). Os principais componentes centrais de um sistema operacional
são:
a) o escalonador de processo, que determina quando e por quanto tempo um
processo é executado em um processador.
b) o gerenciador de memória, que determina quando e como a memória é alocada
aos processos e quais ações tomar quando a memória principal estiver toda ela
ocupada.
c) o gerenciador de E/S, que atende as solicitações de E/S de e para dispositivos de
hardware, respectivamente.
d) o gerenciador de comunicação interprocessos, IPC (Inter Process
Communication), que permite que os processos se comuniquem uns com os
outros.
e) o gerenciador de sistema de arquivos, que organiza coleções nomeadas de dados
em dispositivos de armazenamento e fornece uma interface para acessar os dados
nesses dispositivos.
Quase todos os sistemas operacionais atuais suportam um ambiente de multiprogramação no qual
várias aplicações podem ser executadas concorrentemente. Uma das responsabilidades mais
fundamentais de um sistema operacional é deterrninar qual processador executa um processo e
durante quanto tempo esse processo será executado.
Um programa pode conter diversos elementos que compartilhem dados e que podem ser
executados concorrentemente. Por exemplo, um navegador Web pode conter componentes
isolados para ler a HTML de uma página Web, recuperar a mídia da página (ou seja, imagens,
texto e vídeo) e exibir esta página apresentando seu conteúdo na janela do navegador. Esses
componentes de programa, executados independentemente, mas que realizam seu trabalho em um
espaço de memória comum, sao chamados de threads (fluxos de execução). Normalmente,
muitos processos competem para usar o processador e o escalonador de processos pode basear
suas decisões em diversos critérios, como a importância atribuída a um processo, o tempo
estimado de execução etc.
O gerenciador de memória aloca memória para o sistema operacional e para os processos. Com a
tarefa de garantir que os processos nãoo interfiram na operação normal do sistema operacional ou
uns nos outros, o gerenciador de memória impede que cada processador acesse memória que não
lhe tenha sido alocada. Quase todos os sistemas operacionais atuais suportam memória virtual.
18
Uma outra função central do sistema operacional é gerenciar os dispositivos de E/S
(entrada/saída) do computador. São exemplos de dispositivos de entrada os teclados, mouses,
microfones e scanners. São exemplos de dispositivos de saída os monitores, impressoras e altofalantes.
Dispositivos de armazenamento (por exemplo, discos rígidos, fitas, discos óticos regraváveis ou
não) e placas de rede funcionam como dispositivos de entrada e saída. Quando um processo quer
acessar um dispositivo de E/S, deve emitir uma chamada ao sistema operacional. Aquela
chamada é subseqiientemente utilizada por um driver de dispositivo, que é um componente de
software que interage diretamente com o hardware e, em geral, contém comandos e outras
instruções específicas do dispositivo para realizar as operações de E/S requisitadas.
A rnaioria dos sistemas de computador pode armazenar dados persistentemente (isto e, após o
computador ter sido desligado). Como a memória principal (RAM) é geralmente relativamente
pequena e perde seus dados quando a fonte de energia é desligada (memórias voláteis), são
usados dispositivos secundários de armazenamento persistente (não voláteis), mais comumente
discos rígidos. Um operação de E/S no disco - uma das formas mais comuns de E/S - ocorre
quando um processo requisita acesso à informações que estão em um dispositivo de disco.
Entretanto, o armazenamento secundário é muito mais lento do que os processadores e a memória
principal. O escalonador de disco de um sistema operacional é responsável pela reordenação das
requisições de E/S por disco para maximizar o desempenho e minimizar a quantidade de tempo
que um processo espera pelo tpermino das operações de E/S por disco.
Os sistemas de arranjo redundante de discos independentes, RAID, (Redundant Array of
Independent Disks) tentam reduzir o tempo que um processo espera pela operação de E/S por
disco, utilizando vários discos ao mesmo tempo para atender às requisições de E/S. Existem
vários algoritmos de escalonamento de discos e sistemas RAID, todos objetivando o ganho de
performance.
Os sistemas operacionais usam sistemas de arquivo para organizar e acessar eficientemente
coleções nomeadas de dados, denominadas arquivos e localizadas em dispositivos de
armazenamento. Esses arquivos por sua vez, podem encontrar-se agrupados em áreas
denominadas diretórios, onde um diretório pode apresentar vários subdiretórios e estes outros
mais, sucessivamente em uma estrutura de árvore.
Com frequência, os processos (threads) cooperam para cumprir uma meta comum. Assim, muitos
sistemas operacionais proporcionam comunicação entre processos (IPC) e mecanismos de
sincronização para simplificar essas programações concorrentes. A comunicação entre processos
habilita os processos a se comunicarem via mensagens enviadas entre eles (e entre as threads). A
sincronização fornece estruturas que podem ser usadas para assegurar que processos (e threads)
compartilhem os dados adequadamente.
19
2.1 Tipos de Sistemas Operacionais
Tipos de
Sistemas Operacionais
Sistemas
Monoprogramável/
Monotarefa
Sistemas
Multiprogramável/
Multitarefa
Sistemas
Com Múltiplos
Processadores
2.1.1 Sistemas Monoprogramável/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. Esse único programa monopoliza a
CPU.
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.
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
(RAM)
Dispositivos
E/S
Programa/Tarefa
Sistema Monoprogramável/Monotarefa
20
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.1.2 Sistemas Multiprogramável/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.
Programa_1/Tarefa_1
Programa_4/Tarefa_4
_______
_______
_______
_______
_______
_______
_______
_______
_______
_______
_______
_______
_______
_______
_______
CPU
Memória
Principal
(RAM)
Dispositivos E/S
_______
_______
_______
_______
_______
Programa_3/Tarefa_3
Programa_2/Tarefa_2
Sistema Multiprogramável/Multitarefa
21
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 em
Lotes
Sistemas de
Tempo Compartilhado
Sistemas de
Tempo Real
2.1.2.1 Sistemas em Lotes (Batches)
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.
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.1.2.2 Sistemas de Tempo Compartilhado
Também chamados sistemas de time-sharing, são sistemas que permitem que diversos programas
sejam executados a partir da divisão de tempo da CPU em pequenos intervalos, denominados
fatia de tempo (time slices) ou quantum. Caso a fatia de tempo não seja suficiente para a
conclusão do programa, este é interrompido pelo sistema operacional e substituído na CPU por
outro, enquanto aguarda uma 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.
22
2.1.2.3 Sistemas Operacionais de Tempo Real : Críticos e Não Críticos
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.
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.
Um sistema desse tipo é utilizado quando existem requisitos rígidos de tempo na operação de um
processador ou no fIuxo de dados no sistema. Ele é normalmente utilizado em aplicações
dedicadas e críticas no tempo, como por exemplo, no controle de usinas nucleares, usinas
elétricas, no controle de aeronaves, controle de experimentos científicos, sistemas de imagens
médicas, sistemas de controle industrial, sistemas de injeção eletrônica de combustivel em
motores de veículos, controladores de eletrodomésticos e sistemas bélicos. Um sistema de tempo
real tem limitações de tempo bem definidas, rígidas e fixas.
O processamento tem de ser feito dentro dos limites definidos ou o sistema poderá falhar, como
por exemplo no controle de braços robóticos na construção de carros em uma linha de montagem
automatizada – aqui, o tempo é fator decisivo, diferentemente do que ocorre com um sistema de
tempo compartilhado, em que é desejável , mas não obrigatório, uma resposta rápida. Existem 2
tipos de sistema de tempo real : o crítico e o não crítico.
Um sistema de tempo real crítico procura garantir que as tarefas críticas sejam executadas a
tempo. Essa meta requer que todos os atrasos no sistema sejam limitados, desde a recuperação
dos dados armazenados até o tempo que o sistema operacional precisa para terminar qualquer
solicitação realizada. As limitações de tempo inerentes em aplicações críticas incluem o acesso
aos diferentes tipos de memórias, voláteis ou não, de acesso aleatório ou sequencial. Claramente
pode-se ver que a utilização de armazenamento secundário de qualquer tipo geralmente é muito
limitado e normalmente ausente, sendo desejável que os dados sejam armazenados em memórias
de acesso aleatórias de alta velocidade.
Outros recursos mais avançados, existentes na maioria dos sistemas operacionais também estão
ausentes, como por exemplo a utilização de memória virtual. Essa caracterísitica quase nunca é
encontrada nos sistemas de tempo real, pelos motivos relacionados e, portanto, os sistemas de
tempo real crítico não são compatíveis com a operação dos sistemas de tempo compartilhado, e os
dois não devem ser combinados.
.
Um tipo menos restritivo de sistema de tempo real é o sistema de tempo real não-crítico, no qual
uma tarefa considerada crítica recebe prioridade sobre as demais tarefas não críticas, mantendo
essa prioridade até ser concluída. Como ocorre com os sistema de tempo real crítico, os atrasos
internos ao kernel precisam ser limitados: uma tarefa de tempo real não pode ficar esperando
23
indefinidamente para ser executada.. O tempo real não-crítico é uma meta alcançável que pode
ser combinada com outros tipos de sistemas.
Os sistemas de tempo real não-crítico, no entanto, tem utilidade mais limitada do que os sistema
de tempo real crítico. Considerando sua arquitetura e projeto, eles não são apropriados para
controle industrial, como por exemplo, aplicações robóticas. No entanto, existem várias áreas nas
quais são úteis, incluindo-se aplicações com multimídia, realidade virtual e projetos cientificos
avançados, tais como explorações submarinas e astronáuticas. Esses sistemas precisam de
recursos avançados presentes em sistemas operacionais e que não são apropriados para sistemas
de tempo real crítico. As diferentes versões baseadas no sistema operacional UNIX constituem
bons exemplos de sistemas de tempo real não críticos, assim como o QNX e o VxWorks.
2.2 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
24
2.2.1 Sistemas Fortemente Acoplados : Simétricos e Não Simétricos
Na figura anterior pode-se 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 e um
barramento a ser compartilhada pelos processadores do conjunto, enquanto que nos sistemas
fracamente acoplados cada sistema tem sua própria memória individual. A taxa de transferência
de dados entre CPUs 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 e as
funções também são iguais, diz-se que o sistema é simétrico. No entanto, quando os
processadores são iguais, porém com funções diferentes, a arquitetura denomina-se assimétrica .
A maioria dos sistemas atuais são sistemas de um único processador, ou seja, com somente uma
CPU principal. No entanto, existe uma forte tendência em direção aos sistemas com mais de uma
CPU, os assim chamados sistemas multiprocessados. Tais sistemas tem mais de um processador
em comunicação ativa, compartilhando elementos comuns, tais como o barramento, o relógio do
sistema (clock) e, as vezes, a memória e alguns dispositivos periféricos. A esses sistemas dá-se o
nome de sistemas fortemente acoplados (tightly coupled systems).
Há vários motivos para a existência desses sistemas, como por exemplo uma maior eficiência
(throughput) na execução dos vários processos. Ao se aumentar o número de processadores,
espera-se realizar mais trabalho em menos tempo, mas isso não ocorre. A taxa de aumento de
velocidade com n processadores, entretanto, não é n, mas menor que n, ou seja não é uma relação
linear. Quando vários processadores cooperam em uma tarefa, uma determinada quantidade de
esforço é necessária para manter todas as partes trabalhando corretamente. Esse esforço, em
adição à constante disputa por recursos compartilhados, diminui o ganho esperado dos
processadores adicionais. Da mesma forma que um grupo de n programadores trabalhando em
conjunto não redunda em n vezes a quantidade de trabalho sendo realizada.
Outro motivo para a existência de sistemas com múltiplos processadores é o aumento da
confiabilidade. Se as funções forem distribuídas adequadamente entre os vários processadores, a
falha de um processador não irá interromper o funcionamento de todo o sistema, mas apenas
reduzir a sua velocidade como um todo. Por exemplo, no caso de haver 8 processadores e um
dentre eles vier a falhar, cada um dos outros 7 processadores poderá arcar com o trabalho extra
que estava sendo executado pelo processador defeituoso. O usuário poderá perceber ou não um
pequeno aumento na lentidão do sistema.
À capacidade de continuar a fornecer serviços proporcionais, em sistemas multiprocessados, dáse o nome de degradação normal e, os sistemas projetados para degradação normal tambem são
conhecidos como sistemas tolerantes a falhas. A operação continuada, mesmo com falhas exige
um mecanismo para permitir que a falha seja detectada, diagnosticada e corrigida, se possível for.
Um exemplo dessa arquitetura é o sistema Tandem que utiliza hardware e software duplicados
para garantir a operação contínua, apesar das falhas. O sistema consiste de 2 processadores
idênticos, cada qual com sua própria memória local. Os 2 processadores são conectados por um
barramento comum, sendo que um dos processadores é o primário e o outro, o back-up. Cada
processo sendo executado possui 2 cópias, uma no processador primário e outra no back-up. Em
pontos de verificação previamente estabelecidos (checkpoints), durante a execução normal do
sistema, as informações sobre o status de cada processo (incluindo cópia da imagem da memoria)
são copiadas da máquina primária para a back-up e, se uma falha é detectada, a cópia reserva é
25
ativada e reiniciada a partir do ponto de verificação mais recente. É fácil de se perceber que
sistemas tolerantes à falhas são inerentemente mais caros que sistemas tradicionais.
Os sistemas com 2 ou mais processadores mais comuns utilizam-se do multiprocessamento
simétrico, onde cada processador executa sua própria cópia do sistema operacional, sendo que
essas cópias comunicam-se entre si toda vez que for necessário fazê-lo. Outros sistemas podem
valer-se de multiprocessamento assimétrico, onde cada processador recebe sua própria tarefa
para ser executada. Um processador principal (master) controla todo o sistema e todos os outros
processadores escravos (slaves) procuram o mestre para receber instruções ou continuam a
executar suas tarefas pré definidas. Esse esquema define uma relação do tipo mestre-escravo
(master-slave relationship), onde o processador mestre escalona e aloca trabalho para os
processadores escravos.
Já no multiprocessamento simétrico , SMP (symmetric multiprocessing), todos os processadores
são iguais, não existindo uma relação do tipo mestre-escravo entre os processadores. Cada
processador executa uma cópia do sistema operacional de forma concorrente, partilhando um
barramento (bus) e uma memória, ambos comuns. Nesse modelo de arquitetura operacional,
deve-se ter muito cuidado com as operações de E/S de forma a garantir que as informações
(dados) cheguem ao processador correto. Como as CPUs são independentes, uma pode estar
ociosa enquanto outra está sobrecarregada, resultando em um sistema ineficiente, o que pode ser
minimizado se os processadores compartilharem determinadas estruturas de dados. Um sistema
multiprocessado desse tipo permitirá que processos e recursos, como a memória, sejam compartilhados de forma dinâmica entre vários processadores, podendo diminuir a diferença entre os
processadores. Um sistema desse tipo deve ser cuidadosamente elaborado, como sera visto no
Capitulo 7. Praticamente todos os sistemas operacionais modernos - incluindo o Windows NT,
Solaris, Digital UNIX, OS/2 e Linux agora fornecem suporte a SMP.
A diferença entre multiprocessamento simétrico e assimétrico pode ser resultado de hardware ou
software específicos. Um hardware especial pode diferenciar os múltiplos processadores, ou
então o software pode ser escrito de forma a permitir um mestre e vários escravos. Exemplos : o
sistema operacional SunOS versão 4 da Sun, fornece multiprocessamento assimétrico, enquanto a
versao 5 (Solaris 2) é simétrica, valendo-se do mesmo hardware.
CPU1
CPU2
CPU3
CPU4
CPU5
Barramento Compartilhado
Controlador de memória
Memória compartilhada
Arquitetura de multiprocessamento simétrico
26
2.2.2 Sistemas Fracamente Acoplados : de Rede e Distribuídos
O grande crescimento das redes de computadores e, em especial, da Internet teve um impacto
profundo no desenvolvimento recente dos sistemas operacionais. Quando os PCs surgiram no
final dos anos 70 com a finalidade de serem utilizados para uso "pessoal", eles eram considerados
computadores independentes. Com o uso mais e mais generalizado da Internet no ínicio dos anos
90, os PCs passaram a poder se conectar à redes de computadores. Com a massiva popularização
da WWW (Wide World Web), ou simplesmente Web, em meados da década de 1990, a
conectividade de rede passou a ser considerada um componente essencial de um sistema de
computação, incluindo-se aí os computadores pessoais.
Praticamente todos os PCs e estações de trabalho modernas são capazes de executar browsers
(Netscape, Internet Explorer, FireFox etc.) para acessar documentos to tipo hipertexto na Web.
Sistemas operacionais como o Windows, MacOS, Linux e UNIX, dentre tantos outros agora
também incluem o software de comunicação utilizado na Web, como por exemplo o TCP/IP que
permite a um computador acessar a Internet via uma rede local ou conexão telefônica (dial up).
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.
27
2.2.3 Sistemas em Clusters
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. Em cada servidor, cujo
hardware é identico, o software também deve ser idêntico, i.e., existe um sistema operacional
exatamente igual, com a mesma versão, mesmo firmware, mesmas quotas de disco, quotas de
memória, mesmos usuários e mesmos privilégios, mesmas tarefas/processos sendo executados
etc.
2.2.4 Sistemas Embarcados
Continuando a descer na escala de tamanho dos sistemas operacionais, vemos os sistemas de
computadores de mão e embarcados. Um computador de mão, também conhecido como PDA
(Personal Digital Assistant), é um pequeno computador que cabe em um bolso de camisa e
realiza um pequeno número de funções como por exemplo, atuar como agenda eletrônica ou um
livro de endereços. Sistemas embarcados são executados em computadores que controlam
dispositivos que geralmente não são considerados computadores tais como aparelhos de TV,
fornos de microondas e telefones móveis. Eles tem, muitas vezes, características de sistemas de
tempo real, mas tambem apresentam restrições de tamanho, memória e de consumo de energia
que os fazem especiais. Exemplos desses sistemas operacionais sao o PalmOS e o Windows CE
(Consumer Electronics).
Os telefones celulares também constituem exemplos de sistemas operacionais embarcados, visto
que as várias possibilidades oferecidas por esses aparelhos necessitam de um controle operacional
e, em especial, aqueles com recursos multimídia e possibilidades de acesso à Internet. O sistema
operacional embarcado mais comum é o Symbian, criado para rodar nos celulares "multimídia"
com suporte para cameras fotográficas, MMS, wireless, bluetooth dentre outras funções. Este
sistema operacional é predominantemente baseado em um ambiente gráfico bastante simples. Por
ser pequeno, robusto e modular, como a maioria dos sistemas embarcados, a grande preocupação
do Symbian é evitar ao máximo o desperdício dos recursos do celular, como bateria e memória.
Para isso ele conta com diversos mecanismos que são eficientes ao tratar com esses problemas.
Em sua versão mais nova, a 9.5, foi reduzido o consumo de memória em 30% em relação a
versão anterior. Atualmente o Symbian lidera como sendo o SO mais utilizado em smartphones, á
frente do Linux e do Windows Mobile, entre outros.
2.2.5 Sistemas de Cartões Inteligentes
Os menores sistemas operacionais estão presentes nos assim chamados cartões inteligentes (smart
cards) - dispositivos do tamanho de cartões de crédito que contém um chip de CPU, que na
maioria das vezes é um microcontrolador. Esses sistemas possuem restrições severas de consumo
de energia elétrica e de memória. Alguns deles podem realizar apenas uma única função, como
por exemplo pagamentos eletrônicos, mas outros podem efetuar múltiplas funções no mesmo
cartao inteligente. Esses sistemas são normalmente sistemas proprietários.
Alguns desses cartões inteligentes são orientados à Java, o que significa dizer que a ROM do
cartao inteligente contém um interpretador para a máquina virtual Java (Java Virtual Machine JVM). As pequenas aplicações Java denominadas applets são carregadas no cartão e interpretadas
pelo JVM. Alguns desses cartões podem tratar várias applets Java ao mesmo tempo, gerando um
28
ambiente de multiprogramação (multitask) e a conseqüente necessidade de escalonamento dessas
tarefas (processos).
O gerenciamento de recursos e os aspectos relacionados à proteção, quando 2 ou mais applets
estão presentes simultaneamente, podem se transformar em problemas potenciais, problemas
esses que devem ser tratados pelo sistema operacional contido no cartão.
29
3.0 Arquiteturas de Sistemas Operacionais
3.1 Sistema Monolítico
Um sistema operacional é dito ser monolítico quando todos os seus componentes estão contidos
no seu próprio kernel , i.e, dentro do próprio sistema operacional e, em assim sendo, todo
componente pode comunicar-se diretamente com qualquer outro de maneira rápida, ainda que não
de forma modular e estruturada.
Tal abordagem tende a ser altamente eficaz, dado que muito pouco tempo é gasto nas chamadas
internas ao próprio sistema, entretanto a grande desvantagem dessa abordagem é que por não ser
uma concepção modular, fica muito mais difícil a determinação e correção dos erros mais sutis.
Aplicação
Aplicação
Modo Usuário
Modo Kernel
System Call
Núcleo
do
Sistema
Hardware
30
3.2 Sistemas em Camadas
Na tentativa de se fugir do conceito e da implementação de um sistema operacional monolítico,
tentou-se um outra abordagem, de conceituação mais modular, i.e, o agrupamento de
componentes que executam funções semelhantes.
Nessa nova abordagem, cada camada comunica-se apenas com as camadas imediatamente acima
ou abaixo dela. Dessa forma, as solicitações dos processos devem passar por várias camadas para
serem concluídas e, com certeza, o desempenho (rendimento) do sistema pode ser menor do que o
dos núcleos monolíticos, mas ganha-se na modularidade no projeto, o que é, por si só, uma
enorme vantagem em caso de se depurar o sistema operacional, ainda em seus estágios mais
preliminares. Além disso, outros métodos precisam ser chamados para transmitir dados e
controle, obedecendo-se à uma hierarquia, tal qual a hierarquia existente em uma empresa.
Um dos primeiros sistemas operacionais a abordar o conceito “em camadas” foi o sistema
operacional THE (Technische Hogeschool Eindhoven), elaborado por Dijkstra na Holanda em
1968 e esquematizado abaixo:
Um outro exemplo comumente mencionado ao se tratar de sistemas operacionais em camadas é o
sistema operacional da antiga DEC (Digital Equipment Corporation, que foi comprada pela
Compaq, atual HP), o Open VMS. Este sistema se tornou extremamente aceito no mercado em
função da sua estabilidade operacional, rapidez e pelo baixo número de problemas decorrentes da
utilização dos seus aplicativos (e do seu kernel).
31
3.3 Sistema de Micronúcleo (Microkernel)
Um sistema operacional de micronúcleo fornece, como seu próprio nome sugere, somente um
número pequeno de serviços e com isso, manter seu kernel pequeno e coeso, porém mantendo um
alto grau de modularidade.
Esses sistemas operacionais são normalmente extensíveis, portáteis e escaláveis,o quer requer um
maior nível de comunicação entre módulos, o que, em contrapartida, acarreta uma diminuição do
desempenho do sistema.
Servidor
Arquivo
Servidor
Memória
Servidor
Processo
Servidor
Impressão
Servidor
Rede
Modo Usuário
Modo Kernel
Microkernel
Hardware
32
3.4 Características de um Sistema Operacional
De uma forma geral, algumas das principais características desejáveis nos sistemas operacionais,
do ponto de vista dos usuários (U) e dos projetistas (P) de Sistemas Operacionais são :













eficiência
modularidade
robustez
escalabilidade
extensibilidade
portabilidade
usabilidade
segurança
estabilidade operacional
velocidade operacional
interatividade
preço acessível
boa documentação
(U, P)
(P)
(U, P)
(U, P)
(U, P)
(U, P)
(U, P)
(U, P)
(U, P)
(U, P)
(U)
(U)
(U, P)
Um sistema computacional qualquer é composto pelo Hardware (HW), como por exemplo,
pela(s) CPU(s), pela mais diversos tipos de memória, dispositivos de E/S (impressoras, vídeo,
placas de comunicação), controladores, fios, componentes eletrônicos, conectores etc. e pelo
Software(SW), que pode ser subdividido em aplicativos (comprados e/ou desenvolvidos pelos
usuários) e pelo próprio sistema operacional, normalmente adquirido de um fabricante
especializado.
Considerando-se os tipos de sistemas operacionais descritos anteriormente, reforça-se o conceito
de que multiprogramação é nome dado às técnicas que possibilitam que um sistema
computacional qualquer dotado de uma única CPU seja compartilhado entre os diferentes
processos ativados pelo usuário.
Um sistema operacional eficiente alcança alto rendimento e baixo tempo de retorno. O
rendimento mede a quantidade de trabalbo que um processador pode conduir em um certo
período de tempo. Um dos papeis de um sistema operacional é fornecer serviços a muitas
aplicações. Um sistema operacional eficiente minimiza o tempo gasto oferecendo esses serviços.
Um sistema operacional robusto é tolerante á falhas e confiável - o sistema não falhará devido a
erros isolados de aplicações ou de hardware e, se falhar, ele o fará de forma gradual, minimizando
perda de trabalho e evitando danos ao hardware do sistema. Determinado sistema operacional
fornecerá serviços à cada aplicação, a menos que o hardware venha a falhar.
Um sistema operacional escalável é capaz de usar recursos na medida em que vão sendo
acrescentados ao computador. Se um sistema operacional nao for escalável, rapidamente chegará
a um ponto em que recursos adicionais não serão utilizados totalmente. Um sistema operacional
escalavel pode ajustar imediatamente seu grau de multiprogramação. A escalabilidade é um
atributo particularmente importante dos sistemas multiprocessadores na medida em que são
adicionados mais processadores ao sistema.
33
Idealmente a capacidade de processamento deve crescer proporcionalmente ao número de
processos, embora, na prática, isso nao aconteça. Um sistema operacional extensivel adapta-se
bem às novas tecnologias e fornece capacidades de estender o sistema operacional para executar
tarefas que vão além de seu projeto original.
Um sistema operacional portável é projetado de modo tal que possa operar em muitas
configurações de hardware. A portabilidade de aplicações tambem é importante porque
desenvolver aplicações custa caro - a mesma aplicação deve rodar em uma variedade de
configurações de hardware para reduzir os custos de desenvolvimento. O sistema operacional é
crucial para se obter esse tipo de portabilidade.
Um sistema operacional seguro impede que usuários e software acessem serviços e recursos sem
autorização. A proteção refere-se aos mecanismos que implementam a política de segurança do
sistema.
Um sistema operacional interativo permite que aplicações respondam rapidamente às ações do
usuário ou aos eventos que venham a ocorrer. Um sistema operacional utilizável é aquele que
tem o potencial de atender à uma base significativa de usuários. Esses sistemas operacionais
geralmente fornecem uma interface com o usuario fácil de usar. Sistemas operacionais como o
Linux, Windows XP e MacOS são caracterizados como utilizáveis porque cada um suporta um
grande conjunto de aplicações e fomece as interfaces-padrao com o usuario. Muitos sistemas
operacionais experimentais e acadêmicos não suportam um grande número de aplicações e nem
fornecem interfaces amigáveis com o usuario e, portanto, não são considerados utilizáveis.
34
4.0 Concorrência
Os sistemas monoprogramáveis sub-utilizam os recursos do sistema computacional como um
todo, i.e., a CPU (processador), a utilização da memória principal e todos os periféricos
associados a tal sistema.
Sistema Monoprogramável
x
Sistema Multiprogramável
Ao realizar uma operação qualquer de E/S (I/O) o processo perde o uso da CPU temporáriamente
para retornar, após a operação de E/S ter sido terminada, para o estado em que se encontrava
anteriormente. Observe que nos gráficos acima representados, no sistema monoprogramável,
enquanto uma determinada operação de E/S ocorre, a CPU fica ociosa, ao passo que no sistema
multiprogramável, isso já não ocorre, ou seja, a operação de E/S ocorre em paralelo com a
execução do processo 2.
Há situações em que alguns processos fazem uso mais intensivo da CPU do que de operações de
E/S e, portanto, a utilização da CPU para esses processos torna-se prioritária e essencial – dá-se o
nome de processos polarizados na CPU para tais processos (CPU biased process ou CPU
bounded process), como por exemplo, durante a execução de cálculos matemáticos simulando um
determinado processo físico (simulações financeiras, previsão numérica de tempo etc.).
Por outro lado, há situações em que há uma demanda maior de operações de E/S ao invés de CPU
e, portanto, dá-se o nome de processos polarizados em E/S (I/O biased process ou I/O bounded
process), como por exemplo, durante o processo de desfragmentação de um disco ou de cópia de
arquivos de um disco para outro. Nesses casos, a CPU é utilizada de forma bem menos intensiva,
o que a torna disponível para executar mais processos.
4.1 Interrupções
As interrupções podem ser vistas como intervenções do sistema operacional devido à ocorrência
de algum evento previsto ou imprevisto. Elas podem ocorrer de forma síncrona, i.e., interrupções
que são previstas para ocorrer em intervalos regulares e periódicos, como por exemplo, a
interrupção do relógio do sistema (system clock), que não devem ser confundidas com o relógio
do computador, mostrado abaixo, e que nos informa do dia, mês, ano, hora e minuto.
Já as interrupções assíncronas não tem um tempo certo para ocorrer, podendo ocorrer ou não
durante um determinado período de tempo, como por exemplo, o que ocorre com as chamadas
35
telefônicas oriundas de um telefone fixo ou celular. Elas podem ocorrer ou não ao longo de um
determinado período de tempo e, se ocorrerem, não há como prever quando elas ocorrerão,
quanto tempo durarão e quantas vezes elas acontecerão. Isso confere um caráter aleatório a esses
acontecimentos, sendo portanto chamados de assíncronos.
As interrupções, quando ocorrem, desviam o fluxo de execução anteriormente sendo executado
pela CPU para uma rotina de tratamento da interrupção própria para aquele tipo de interrupção,
sendo necessário para isso que a interrupção traga consigo a informação de quem a gerou. As
interrupções podem ser geradas internamente a um programa, pelo próprio sistema operacional ou
por um evento externo, tal como por exemplo, uma interrupção gerada pelo hardware. Cada
interrupção possui uma rotina de tratamento associada, e a associação entre elas é mantida em
uma estrutura denominada vetor de interrupção.
As interrupções ainda podem ser do tipo internas e externas:
a)Internas: há instruções de máquina que são vistas como sendo interrupções internas, como
por exemplo a instrução INT das CPUs Intel 8080 e 8085. Essas instruções ao serem executadas
pela CPU gera um efeito semelhante à de uma interrupção externa. Uma exceção é um tipo de
interrupção normalmente associada à um erro como por exemplo um estouro de capacidade
(overflow) ou por uma tentativa de divisão por zero.
b)Externas: interrupções externas são aquelas geradas pelo SO ou por algum dispositivo
periférico (HW) pertencente ao sistema computacional, como por exemplo, o término de uma
dterminada operação de E/S em disco ou impressora, ou o clickar de algum dos botões do mouse,
dentre tantos outros exemplos.
Para que uma interrupção possa ser atendida pela CPU, algumas condições essenciais devem
ocorrer, como por exemplo as macro-ações dadas acima (salvamento dos registradores,
identificação da causa da interrupção, processamento do código inerente ao atendimento daquela
interrupção em particular, a restauração dos conteúdos dos registradores anteriormente salvos e o
retorno ao ponto em que a interrupão ocorrreu.
36
As interrupções podem ser do tipo mascaráveis ou não mascaráveis. Se a interrupção externa
puder ser desabilitada pela CPU ela é denominada mascarável (masked interrupt) e será ignorada,
não recebendo tratamento. Caso contrário, ela é chamada de interrupção não-mascarável ou do
tipo NMI (non-masked interrupt) e o tratamento será obrigatório.
As interrupções podem ser ou não aninhadas, i.e, uma determinada interrupção pode ser
interrompida por uma outra mais prioritária e assim por diante. Como há uma prioridade
associada à cada interrupção, uma determinada interrupção só pode ser interrompida por uma
outra interrupção de prioridade maior. A hierarquia deve ser respeitada, entretanto, mesmo as
interrupções de prioridade menor devem ser atendidas ainda que mais tardiamente, portanto a
regra geral é que toda interrupção deve ser atendida.
4.2 Operações de Entrada e Saída (E/S):
Inicialmente, a CPU executava todas as instruções de E/S e, para isso, essas instruções tinham
que conter informações detalhadas sobre os diversos periféricos tais como por exemplo as trilhas
e setores que poderiam ser lidos ou gravados em uma unidade de disco.
Com o passar do tempo, o controlador (ou interface) criou a independência entre a CPU e os
dispositivos de E/S, pois este faz a intermediação entre os dois. As características dos dispositivos
ficaram a cargo do controlador e as instruções de E/S foram, portanto, simplificadas.
O monitoramento do dispositivo e a transferência de dados entre a CPU e os periféricos evoluiu
com o tempo, mas algumas das técnicas utilizadas até hoje são dadas abaixo:
4.2.1 E/S Controlada por Programa
A CPU inicia a transferência e indaga continuamente o periférico sobre o final da instrução de
E/S – essa atitude é um grande desperdício de tempo da CPU.
4.2.2 Polling
O status do dispositivo periférico era testado em intervalos de tempo, liberando a CPU para a
execução de outro(s) programa(s). No caso de existirem muitos periféricos, o sistema interrompia
freqüentemente o processamento para testar o término exato da operação.
4.2.3 E/S Controlada por Interrupção
A CPU envia um comando para o controlador que se encarrega de ler o disco e armazenar na
memória ou em registradores internos (próprios). Ao término, o controlador sinaliza uma
interrupção ao processador que, ao tratá-la, busca os dados solitados. Várias operações de E/S
podem ser executadas paralelamente, porém toda a transferência de dados entre a memória e os
periféricos exige utilização da CPU.
4.2.4 DMA (Direct Memory Access)
O controlador recebe informações de onde os dados se encontram, qual o dispositivo de E/S
envolvido, posição inicial de memória onde os dados serão lidos ou gravados e o tamanho do
bloco de dados. Com essas informações, a transferência é realizada pelo controlador (que assume
temporariamente o controle do barramento), utilizando para essa transferência uma área de
memória temporária denominada buffer, descrita a seguir.
4.2.5 Canal de E/S (I/O Channel)
É um processador com controle total sobre os dispositivos de E/S a ele conectados (vários
controladores), o qual executa um programa de canal (armazenado na memória RAM) que
especifica os dispositivos e os buffers e controla possíveis erros da transferência, sinalizando a
CPU ao final da operação.
37
4.2.6 Processador de E/S (IOP – Input Output Processor)
O canal passou a ter sua própria memória de modo que a intervenção da CPU se tornou mínima,
deixando a maior parte do trabalho de transferência de dados para o processador de E/S (ou IOP –
Input Output Processor).
4.2.7 Buffers
Dá-se o nome de buffer à uma parte da memória principal ou secundária para possibilitar a
transferência de dados entre os periféricos e a CPU. Essa área de buffer é temporária,
normalmente alocada dinamicamente e visa minimizar as diferenças de velocidade do
processamento da CPU e dos dispositivos de E/S e mesmo entre os vários dispositivos de E/S.
A unidade lógica que normalmente é associada à utilização de buffers é denominada “registro” e
que é normalmente formatado em função de um determinado dispositivo de E/S, como por
exemplo, uma linha a ser impressa, a leitura de cada caracter de teclado) ou da leitura e/ou
gravação de um registro lógico de um arquivo.
O dispositivo transfere um dado para o buffer e pode iniciar nova leitura. A CPU pode manipular
o dado no buffer simultaneamente às leituras do dispositivos. Na gravação o processo é
semelhante, com a CPU alocando dados no buffer, sendo que neste podem existir dados lidos mas
não processados, ou processados e ainda não gravados.
4.2.8 Spooling (Simultaneous Peripheral Operation On-Line)
Surgiu como opção para um melhor aproveitamento da CPU e dos dispositivos periféricos
utilizados no início da década de 60 e objetivava principalmente, a impressão.
Ao invés de enviar os resultados gerados pelos diferentes jobs diretamente para a impressora e
ficar esperando o término da impressão para iniciar a execução de outro programa, a CPU envia
os resultados de cada job para um arquivo intermediário que no início ficava armazenado em um
fita magnética. Este arquivo era então lido e então, impresso, sendo que a ordem de impressão
dos jobs era determinada pelas prioridades a eles atribuídas. O nome de spooler era dado ao
sistema que gerenciava as impressões.
Atualmente, as funções atribuídas ao spooler ainda se encontram presentes em diversos
servidores de impressão, com funções e características bem mais sofisticadas do que as antigas.
4.3 Reentrância
Reentrância consiste na capacidade de um determinado processo apresentar um código reentrante,
i.e., um código especialmente elaborado para ser compartilhado, na memória, por diversos
usuários. Dessa forma há normalmente apenas um cópia carregada para a memória e, em sendo
assim, este código, por razões óbvias, não pode ser alterado.
A reentrância se aproveita do fato de que todo programa pode ser desenvolvido de tal forma que a
área de código deste se encontra separada da área de dados e desta forma cada usuário pode estar
em um ponto diverso do programa, manipulando seus próprios dados. Vários utilitários do
sistema tais como editores, compiladores, linkeditores são exemplos de códigos reentrantes.
38
4.4 Proteção ao Sistema
Em ambientes onde muitos usuários compartilham recursos e dados, o sistema operacional deve
prover mecanismos que garantam:
a) Integridade dos dados de cada usuário: um programa não pode acessar a área de memória
do
outro (acidentalmente ou não). O mecanismo de gerência de memória determina a forma de
controle.
b) Compartilhamento de dispositivos de E/S: um programa só pode utilizar um dispositivo de
E/S no momento em que o primeiro programa o liberar.
c) Compartilhamento de arquivos: o SO provê mecanismo de controle de acesso à arquivos de
modo que as informações do usuário permaneçam consistentes.
d) Compartilhamento de CPU: o uso da CPU deve ser compartilhado entre os diferentes
programas de maneira rígida, pois é o principal componente do sistema.
4.5 Modos de Execução
Cada vez que o usuário necessita utilizar um recurso do sistema computacional ele o solicita ao
Sistema Operacional através de funções (rotinas) do próprio sistema denominadas de System
Calls ou System Services ou Sytem Internals. Essas rotinas, para acessarem os recursos
disponibilizados, devem possuir mecanismos de proteção. O mecanismo mais utilizado nos
sistemas multiprogramáveis é chamado de modo de execução. Consiste de uma característica que,
associada ao programa em execução, determina se ele pode executar certas instruções ou funções
do sistema operacional. O modo corrente é armazenado em um registrador especial da CPU, o
qual é verificado pelo hardware e assim executar ou não a instrução.
Há 2 modos de execução:
a) Modo Usuário: o programa só executa instruções que não afetem diretamente os outros
programas (instruções não privilegiadas).
b) Modo Supervisor (monitor ou kernel): qualquer instrução pode ser executada, mesmo rotinas
do sistema (instruções privilegiadas). Em uma leitura, por exemplo, o programa solicita o acesso
ao disco ao Sistema Operacional que verifica se o arquivo pode ser acessado. Se sim, muda o
Modo de Execução para supervisor, realiza a operação de leitura e retorna o Modo de Execução
para usuário, continuando o processamento. O sistema operacional sempre executa em modo
supervisor, pois é responsável pelo compartilhamento dos recursos, e deve possuir esta
capacidade.
39
5.0 CPU – Unidade Central de Processamento (Central Processing Unit)
A CPU é composta por vários blocos funcionais interligados como por exemplo a unidade de
controle, a unidade de busca e decodificação, a ULA (Unidade Lógica e Artmética), os
registradores etc.
Os registradores são áreas destinadas ao armazenamento temporário de informações, localizadas
no interior da CPU, apresentando tempo de acesso mais rápido do que as palavras da memória
principal. Distinguimos 2 conjuntos básicos de registradores:
5.1 Registradores Visíveis
São considerados registradores visíveis ao programador todos aqueles registradores considerados
como sendo de uso geral, como por exemplo, o acumulador, os registradores r0, r1, ..., rn (ou
quaisquer que sejam os seus nomes). Além desses há ainda os registradores de controle e de
funções especiais tais como o PC, o SP e o PSW. O registrador PC (program counter) contém o
endereço de memória da próxima instrução a ser buscada; o registrador SP (stack pointer) contém
o endereço de memória do topo da pilha (stack) e o registrador PSW (processor status word) é a
palavra de estado da CPU que contém os flags, que nada mais são do que indicadores específicos
da ocorrência de determinadas condições que refletem o estado da última instrução/operação
lógico aritmética realizada.
5.2 Registradores Invisíveis
Os registradores “invisíveis” são todos aqueles registradores utilizados para controle interno da
CPU, como por exemplo os registradores MAR, MDR etc. e utilizados somente para a
microprogramação interna à própria CPU. Os programadores não possuem acesso a esses
registradores.
Funcionalmente, a CPU pode encontrar-se em 1 dentre 2 estados: o de suspensão ou em
processamento. No estado de suspensão, ela aguarda por um evento externo (geralmente uma
interrupção) para passar ao estado de processamento; no estado de processamento, ela realiza
continuamente um ciclo de busca, decodificação e execução de instruções.
1) A fase de busca consiste na leitura da palavra de memória cujo endereço está
especificado no registrador PC.
2) A fase de decodificação consiste em desmembrar a instrução em seus diversos
componentes (código de operação e operandos).
3) Como uma instrução pode ser codificada em mais de uma palavra de memória, as fases
de busca e decodificação são, na verdade, inter-dependentes.
4) Ao final da fase de busca/decodificação, o registrador PC deverá conter o endereço da
palavra seguinte à última palavra da instrução em questão.
A execução da instrução assemelha-se ao conceito matemático de função: uma operação
(especificada pelo código de operação) é realizada sobre os operandos (especificados por modos
de endereçamento). Há instruções que envolvem zero (0) , 1 ou 2 operandos.
Para ser executada, cada instrução (especificada em um programa em linguagem de montagem
(Assembly Language)) é decomposta em uma série de microinstruções, armazenadas em uma
memória interna à CPU, denominada de memória de microprograma.
40

As CPUs do tipo CISC (Complex Instruction Set Computer) possuem microprogramas
complexos, onde a maior parte das instruções executadas pela CPU são quebradas em
instruções ainda menores, denominadas microinstruções ou microcódigo. Esse
microcódigo fica armazenado na memória de microcontrole, interna à CPU.

As CPUs do tipo RISC (Reduced Instruction Set Computer) possuem, em seu repertório,
instruções já bastante próximas (ou mesmo idênticas) às microinstruções, algumas vezes
dispensando a existência do microprograma.
Os modos de endereçamento especificam a localização dos operandos, que podem estar em 3
localidades: em registradores internos da CPU, na memória principal ou em registradores das
controladoras dos periféricos (normalmente denominados portas). Alguns modos importantes de
endereçamento são:






Modo registrador:
Modo absoluto:
Modo imediato:
Modo indireto:
Modo base+deslocamento:
Modo de entrada/saída:
mov
mov
mov
mov
mov
out
r0,r1
234,r2
#421,sp
[r3],r0
[r3+20],r2
r3,255
; in
300,r1
Algumas CPUs possuem instruções que admitem mais de um operando externo (que não está em
um registrador da CPU); outras admitem, no máximo, uma referência a dados externos por
instrução.
Para implementar alguns mecanismos básicos de proteção em um sistema operacional, é essencial
que a CPU possa funcionar em pelo menos 2 modos de execução: o modo usuário (ou não
privilegiado) e o modo supervisor (Kernel ou privilegiado).





Funcionando em modo supervisor (ou kernel), a CPU pode executar qualquer instrução
do seu repertório de instruções, sem restrições quanto à localização dos operandos.
No modo usuário, a tentativa de executar algumas instruções especiais causa exceções,
como por exemplo a instrução HALT (parar, em Alemão). A execução dessa instrução
instrui a CPU a interromper imediatamente todo e qualquer processamento, fazendo-a
entrar no modo idle . A única forma de tirar a CPU desse estado de suspensão é através
de um reset do hardware ou momentaneamente através de uma interrupção externa.
O modo corrente de funcionamento é armazenado em um bit da PSW (processor status
word) e, nesse caso, o valor 0 pode significar modo Supervisor e o valor 1 pode significar
modo Usuário.
A transição do modo kernel para o modo usuário não oferece problemas desde que se
tenha as prerrogativas (privilégios) para fazê-lo, bastando para isso colocar o bit
correspondente na PSW em “1” ou em “0”;
Já a transição contrária deve ser feita através de uma instrução especial (TRAP) que, ao
mesmo tempo que inverte o valor do referido bit, provoca a chamada a uma subrotina
situada em um endereço bem conhecido pelo sistema operacional.
5.3 CPU, Comunicação e Periféricos
São atualmente conectados ao barramento através de interfaces controladoras e acionados através
de comandos parametrizados enviados pelas CPUs, mas a situação nem sempre foi assim.
41
O diálogo entre a CPU e a controladora envolve operações de leitura e escrita nos registradores
internos da controladora. Esses registradores possuem endereços e o acesso a eles se faz
basicamente de duas maneiras, dependendo da arquitetura escolhida:
 através de instruções especiais para entrada e saída, como IN e OUT (E/S direta ou via
IOP);
 através de instruções regulares da CPU, que utilizam uma faixa de endereços não
direcionada à memória principal (E/S mapeada).
Há 3 técnicas importantes para o tratamento de entrada e saída:
5.3.1 Loop de Status




A CPU comanda a operação desejada, escrevendo os parâmetros e o código de operação
nos registradores da controladora.
A conclusão da operação é aguardada em uma malha, na qual são lidos registradores de
estado da controladora até que algum padrão de bits neles se evidencie.
Durante a malha, a CPU não pode ser dedicada a outras atividades.
Normalmente a malha não é repetida indefinidamente, mas até um número máximo de
vezes (timeout), para evitar o monopólio da CPU.
5.3. 2 Interrupção






A CPU comanda a operação desejada, escrevendo os parâmetros e o código de operação
nos registradores da controladora, dedicando-se, em seguida, a outras tarefas.
Quando o periférico conclui a operação, a controladora interrompe a CPU, depositando
no barramento sua identificação, a identificação da CPU a ser interrompida e o sinal de
interrupção.
As CPUs, ao fim de cada ciclo de busca/decodificação/execução, verificam a existência
de pedidos de interrupção (caso não estejam mascaradas).
Baseada na identificação do periférico, a CPU interrompida simula uma chamada a uma
subrotina de atendimento da interrupção, situada a partir de um endereço de memória
calculado em função da identificação da controladora. São empilhadas informações que
possibilitem o retorno inequívoco ao ponto de execução que está sendo interrompido (PC
e PSW).
A subrotina de atendimento: empilha todos os registradores de uso geral (r0, r1, ...);
avalia os resultados da operação comandada (lendo registradores de estado da
controladora); realiza, se necessária, a transferência de dados entre a memória e a
controladora; comanda uma próxima operação, se for o caso.
Ao terminar seu processamento, a subrotina de atendimento desempilha os registradores
de uso geral e utiliza uma instrução especial de retorno de subrotina (IRET), que
desempilhará a PSW e o PC; isto causará o retorno ao ponto onde o processamento foi
interrompido.
Há vários tipos de operações que podem gerar diversas interrupções ao longo de seu
processamento. Portanto, muitas vezes, as subrotinas de atendimento devem implementar uma
máquina de estados, a fim de processar corretamente os diversos estágios da operação.
42
5.3.3 Via DMA (Direct Memory Access)





É um processador que se ocupa da transferência de dados entre a controladora e a
memória principal.
A programação do DMA pode ser explícita ou implícita ao comando de entrada e saída
enviado pela CPU à controladora do periférico. Devem ser informados: o endereço de
memória a partir do qual os dados serão lidos ou escritos; o número de palavras a
transferir; o sentido da transferência (controlador  memória, em caso de leitura ou
memória  controlador, em caso de escrita).
A transferência dos dados se dá sem intervenção da CPU, diretamente entre a
controladora e a memória principal através de uma técnica denominada de roubo de ciclo
(cycle stealing), onde o controlador de DMA rouba ciclos da CPU.
A operação comandada só é considerada concluída quando os dados já estiverem
transferidos.
O DMA pode ser usado tanto em tratamento por loop de status quanto em tratamento por
interrupção.
Ao perceber um sinal de interrupção pendente, a CPU deverá simular uma chamada à subrotina
de atendimento:
 É necessário que esta subrotina esteja na memória principal, armazenada a partir de um
determinado endereço.
 Como várias controladoras podem enviar pedidos de interrupção a uma CPU, o comum é
organizar uma tabela, denominada vetor de interrupções, situada em um endereço de
memória bem conhecido pela CPU (pode haver um registrador que armazene este
endereço).
 Cada entrada desta tabela refere-se a uma fonte externa de interrupção e deve conter,
dentre outras informações, o endereço da subrotina de atendimento específica daquela
interrupção.
 De posse da identificação da controladora (informada à CPU juntamente com o pedido de
interrupção), após empilhar o PC e a PSW, a CPU indexa esta tabela, atribuindo ao PC o
endereço da subrotina de atendimento.
A fim de priorizar o atendimento de alguns periféricos sobre outros, as CPUs costumam associar
níveis de prioridade ao atendimento de interrupções, permitindo o aninhamento de subrotinas de
atendimento:







Em um campo da PSW, fica guardado o nível corrente de funcionamento.
Se a CPU está em processamento normal (não atendendo interrupções) o nível corrente é
0.
Quando uma controladora interrompe, deve informar à CPU o nível da interrupção que
está solicitando.
A CPU só admite interrupções de nível superior ao corrente; do contrário, o pedido ficará
pendente até que a CPU possa atendê-lo.
Quando uma interrupção é atendida, o PSW é empilhado juntamente com o PC e o nível
corrente na PSW passa a ser o nível desta interrupção.
Ao retornar do atendimento (instrução IRET – Interruption Return), a CPU desempilha
os valores do PC e da PSW e o nível corrente volta ao que era imediatamente antes do
atendimento. A função de salvar e restaurar os conteúdos de todos os registradores
internos à CPU é de responsabilidade do programador, sendo vital que ele o faça.
O assim chamado “empilhamento” dos conteúdos dos registradores da CPU dá-se em
uma área de memória RAM cujo endereço é dado pelo conteúdo do registrador SP (Stack
43
Pointer), ou ponteiro de pilha, cujo conteúdo vai sendo alterado à medida em que os
dados vão sendo “empilhados”. O “desempilhamento” desses mesmos conteúdos deve ser
feito na ordem exata em que foram “empilhados”, caso contrário o conteúdo de um
registrador pode ser alocado em outro registrador, o que pode acarretar erros no
processamento assim que a CPU voltar ao fluxo de processamento anterior à interrupção.
Concluindo: o registrador PSW, no nosso modelo, deverá conter os seguintes campos:



Flags (indicadores, como Zero, Carry, Negative, Overflow, Parity, etc...);
Modo Corrente de Execução (0 = supervisor, 1 = usuário);
Nível Corrente de Aninhamento de Interrupções.
44
6.0 Processos
O conceito básico de processo é o de um programa sendo executado pela CPU e que possui seu
próprio contexto operacional. Os processos podem ser de natureza interna ou externa. Os de
natureza interna são os processos internos ao próprio sistema operacional e os de natureza externa
são aqueles que tem origem em aplicativos desenvolvidos ou ativados pelo usuário, como por
exemplo, um programa Java, um editor de texto, um aplicativo para processamento de imagens e
sons etc.
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.
6.1 Componentes do Processo
Conforme já mencionado, um processo pode ser entendido inicialmente como um programa em
execução, que tem suas informações mantidas pelo sistema operacional e em um 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. O mesmo é válido para um sistema monousuário mas multitarefa,
onde o único usuário tem a “impressão” de que todos os processos estão sendo executados
simultaneamente – essa impressão advém da velocidade de execução da CPU. Se a CPU em
questão for lenta, essa impressão de simultaneidade se dissipa rapidamente e o usuário passa a ter
a percepção de que o sistema como um todo está lento.
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 armazenadas em uma área segura,
para que a CPU possa retomar a sua execução 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.
6.2 Contexto e PCB
Cada processo possui seu próprio ambiente de execução que é denominado contexto de execução
desse processo. Um mesmo processo, dependendo do contexto no qual está sendo executado em
um determinado sistema computacional poderá eventualmente obter resultados diferentes, como
por exemplo no caso de um processo sendo executado em um ambiente operacional no qual há
cotas de utilização de disco limitadas e o mesmo processo sendo executado em um outro
ambiente operacional no qual não há cotas de disco estabelecidas. No primeiro caso, o processo
45
poderá ser abortado pelo sistema operacional por tentar utilizar mais espaço em disco do que o
permitido e no segundo caso ele poderá ser executado até o final sem qualquer problema.
O sistema operacional utiliza estruturas de dados conhecidas como Bloco de Controle de
Processos (PCB – Process Control Block) que são associadas a cada processo em execução. Se
houver 100 processos sendo executados em um determinado sistema operacional, haverá 100
PCBs, cada uma delas associada a um processo. Se houver 1000 processos (internos e/ou
externos) no total, haverá 1000 PCBs.
A estrutura de uma PCB pode variar de sistema para sistema, assim como os dados nela
armazenados, mas de uma forma geral, há uma estrutura comum, em maior ou menor grau, que é
detalhada abaixo, onde PID designa a identificação do processo (Process Identification) .
PID Ponteiro para a área de memória deste PCB
PID
Ponteiro para o PCB deste processo
PID
Ponteiro para o PCB deste processo
PID
Ponteiro para o PCB deste processo
Registradores internos à CPU
PID
Ponteiro para o PCB deste processo
PID
Ponteiro para o PCB deste processo
Prioridade atual do processo
Status operacional do processo
PID
Ponteiro para o PCB deste processo
Identificação do processo (PID)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Nome simbólico do processo
PID
Ponteiro para o PCB deste processo
Quotas de memória
Quotas de disco
Dados sobre o processo pai
Dados sobre cada processo filho
Informações adicionais
46
Na figura anterior, do lado direito, há um campo denominado Registradores internos à CPU e
que é constituído por vários outros campos, cada campo contendo o conteúdo de cada um dos
registradores internos à CPU, i.e., se a CPU tiver 8 registradores esse campo terá 8 sub-campos,
por assim dizer, e se ela tiver 10, 12, 16 ou n registradores haverão 10, 12, 16 ou n sub-campos,
conforme detalhado na figura abaixo, onde uma CPU hipotética contem n registradores no total.
Registradores internos à CPU
Conteúdo do PC
Conteúdo do SP
Conteúdo do PSW
Conteúdo do acumulador
Conteúdo do R0
Conteúdo do R1
:::::::::::::::::::::::::::::::::::::::::::::::::
::
:::::::::::::::::::::::::::::::::::::::::::::::::
Conteúdo do Rn
A mesma abordagem pode acontecer para outros campos do PCB, i.e, mais ponteiros indicando o
endereço inicial de outras estruturas, mas isto é função da implementação do sistema operacional
e não uma regra rígida.
O sistema operacional gerencia os processos através das system calls, que realizam diversas
operações , tais como acesso à discos, alocação e dealocação de áreas de memória, verificação de
privilégios de usuários, criação, remoção, eliminação, sincronização e suspensão de processos,
dentre muitas outras funções.
O contexto de um processo pode ainda ser subdividido em 3 elementos básicos, que integrados,
fornecem o contexto de qualquer processo:
a) contexto de software: o contexto de software se aplica às características operacionais do
processo, como por exemplo a identificação do processo, a PID (Process Identification), os
privilégios que este processo pode possuir, a identificação do usuário que o iniciou, quotas de
utilização de disco e memória, número máximo de arquivos simultaneamente abertos,
tamanho dos buffers para operações de E/S etc. Dentre todos esses, destacam-se :
1) 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.
2) Quotas: são os limites de recursos do sistema que um processo pode alocar, como a
á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.
3) Privilégios: dizem respeito principalmente às prioridades assumidas pelo processo
durante sua execução.
47
b) contexto de hardware: o contexto de hardware se aplica principalmente aos conteúdos dos
registradores da CPU. A manutenção desse contexto é fundamental para a implementação de
sistemas de tempo compartilhado (time sharing). Essa é uma característica básica em
qualquer sistema do tipo multitarefa e a troca de um processo por outro na CPU, realizada
pelo sistema operacional é conhecida como mudança de contexto (context switching) . A
mudança de contexto consiste em salvar os conteúdos dos registradores da CPU e carregá-los
com os conteúdos dos registradores do processo que está ganhando a CPU.
c) espaço de endereçamento na memória: o espaço de endereçamento é a área de memória
atribuída pelo sistema operacional ao programa que após ser carregado para a memória será
executado. Essa área pertence somente ao processo, devendo ser protegida dos demais
processos.
6.3 Estados Básicos de um Processo
Um processo em um sistema do tipo multitarefa não é executado todo o tempo e de forma
contínua pela CPU. Durante o período de sua “existência” ele transita entre vários estados e esse
transitar é gerenciado pelo sistema operacional. Para efeitos de simplicidade vamos considerar
um conjunto de 3 estados básicos nos quais um determinado processo pode estar:
EXECUTANDO (running), PRONTO (ready) e ESPERANDO (waiting) o estado
ESPERANDO é também conhecido por ESPERA ou SUSPENSO.
O conjunto desses 3 estados ilustra o que é conhecido como diagrama de estados ou máquina
de estados de um processo por possibilitar a visualização da mudança de um estado para outro,
mudança essa que pode ser ocasionada pelo sistema operacional ou às vezes pelo próprio
processo que pode, por exemplo, se auto-suspender por um determinado tempo ou esperar que um
outro processo termine ou comece.
Execução
Ativação/início
Esperando
Processo 45
Processo 89
finalização/término
Pronto
Processo 3
Processo 10
Processo 14
À cada um desses estados, representados nessa máquina de estados, está associada uma estrutura
de dados parecida com um lista encadeada que cresce e diminui dinamicamente (simbolizado pela
seta de 2 extemidades) e que contém as identificações de todos os processos alocados nesses
estados. Como cada processo possui sua própria PCB é possível a restauração do contexto de
48
cada um desses processos a partir das informações que constam nas respectivas PBCs associadas
aos processos.
Na ilustração acima, vê-se que há 2 processos em estado de espera e 3 processos prontos para
serem executados e somente 1 processo em execução. Mesmo se fosse o caso de um sistema
multiprocessado ,i.e., com várias CPUs , a regra ontinua valendo, pois cada uma dessas CPUs
estará executando somente 1 processo durante um determinado intervalo de tempo, intervalo esse
cujo valor é fixo e constante. Esse intervalo de tempo também recebe o nome de quantum e os
diferentes processos poderão receber diferentes valores de quantuns em função de sua prioridade
pré-estabelecida quando da sua criação ou quando do seu escalonamento. Quanto maior o número
de quantuns atribuídos a um processo, maior será o tempo que esse processo terá para ser
executado pela CPU.
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/ativaçã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 em execução na CPU
até que seja interrompido ou termine sua execução. Neste estado, em um sistema
monoprocessado, i.e., com somente uma única CPU, há somente um processo.
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.
Saída/término: é o estado final do processo, quando este termina seu processamento. Vários
processos podem estar neste estado, ao mesmo tempo, aguardando o seu desviculamento efetivo e
por completo do sistema computacional.
49
6.4 Mudanças de Estado
Um processo muda de estado diversas vezes durante sua permanência no sistema devido aos
eventos ocorridos durante sua execução. As mudanças possíveis são:
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.
6.5 Tipos de processos
Além dos processos do usuário, a CPU também executa processos internos 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 de um
sistema operacional. Todos os processos internos ao sistema operacional são executados, sempre,
com certa prioridade, concorrendo com todos os processos do usuário.
Os processos em execução, do usuário, podem ser de dois tipos diferentes, de acordo com suas
características de utilização da CPU e periféricos:
6.5.1 Processo CPU-Bound: é aquele processo que faz utilização intensa da CPU. Ele ganha uma
fatia de tempo (quantum) e a utiliza por inteiro, sem desperdiçar nenhum tempo. É o caso de
programas científicos, de aplicações numéricas diversas, de aplicações estatísticas, pesquisas
matemáticas, e também na área de simulação. Esses processos normalmente fazem pouca ou
nenhuma entrada de dados (input), e muito processamento.
6.5.2 Processo I/O-Bound: é aquele tipo de processo que utiliza muito mais os dispositivos de
E/S do que CPU. Aplicações que envolvem banco de dados, onde se fazem consultas e
atualizações constantes em arquivos em disco são bons exemplos deste tipo de processo. De
acordo com essas características, podemos dizer que este tipo de processo permanece mais tempo
em espera do que própriamente em execução, ocupando a CPU por períodos mínimos de tempo.
50
Com relação às formas de interação com o(s) usuário(s), os processos podem ser de dois tipos: os
de plano frontal (foreground) e os de plano de fundo (backgroundl). Os processos de plano de
fundo podem dar a impressão de que não estão sendo executados pela CPU, já que aparentam não
estar se comunicando com o(s) usuário(s), entretanto, eles continuam a ser executados e a
disputar a CPU e o seu precioso tempo.
6.5.3 Processo em Foreground: é aquele processo com está interagindo diretamente com o
usuário, como por exemplo quando o usuário está atualizando os dados de uma planilha
eletrônica, ou alterando algum texto através de um editor de texto, ‘navegando’ na Internet,
compilando um programa etc. Múltiplas janelas, cada uma delas com um aplicativo sendo
executado, podem estar abertas e não minimizadas, entretanto, somente uma delas está ativa. Esta
janela ativa constitui um exemplo de processo em foreground.
6.5.4 Processo em Background: é aquele processo que foi ativado em algum instante pelo
usuário e que está momentaneamente sendo executado em outro plano de execução que não o
frontal, ou seja, que não está interagindo diretamente com o usuário. São exemplos de processos
em background todos aqueles que foram ‘minimizados’ pelo usuário, como por exemplos, sessões
de download que ainda estão ocorrendo, uma ou mais janelas de navegação pela Internet, abertas,
acessadas e minimizadas ou não pelo usuário. O ato de minimizar uma determinada janela, com
seu respectivo aplicativo sendo executado não caracteriza um processo em background. Múltiplas
janelas, cada uma delas com um aplicativo sendo executado, podem estar abertas e não
minimizadas, entretanto, somente uma delas está ativa (foreground) – todas as demais janelas
constituem-se de exemplos de processos em background.
51
7.0 Gerenciamento da CPU
A idéia central que tornou viável a implementação dos sistemas multiprogramáveis foi a
possibilidade da CPU poder ser compartilhada entre diversos processos, ou em outra palavras,
poder ser multiplexada no tempo entre esses diversos processos. Para isso, todo sistema
multiprogramável possui um critério para determinar qual a ordem na escolha dos processos para
execução entre os vários que concorrem pela utilização da CPU (processador).
O(s) critério(s) utilizado(s) na seleção de qual processo será executado é uma das principais
funções realizadas por um sistema operacional e é conhecido como escalonamento (scheduling).
O processo interno do sistema operacional responsável pelo escalonamento dos processos é
chamada de escalonador (scheduler) .
Os principais objetivos do escalonamento são :
a) manter a CPU “ocupada” a maior parte do tempo
b) balancear a utilização do processador entre os diversos processos
c) maximizar a eficiência (throughput) do sistema computacional como um todo
d) oferecer tempos de resposta razoáveis para os usuários
Esses objetivos devem ser atendidos de forma que o sistema procure tratar todos os processos de
forma igualitária, evitando que um processo venha a monopolizar o tempo da CPU, ao mesmo
tempo emque procura evitar que um outro processo fique indefinidamente esperando pela
utilização da CPU (starvation). Para atender alguns desses objetivos conflitantes, os sistemas
operacionais devem levar em consideração algumas das principais caracteristicas dos processos,
ou seja, se esse processo é do tipo batch, interativo, CPU-bound ou I/O-bound, requisitos de
memória desses processos etc. Sistemas de tempo real ou de tempo compartilhado tambem são
aspectos fundamentais para a implementação de uma politica adequada de escalonamento.
A mesma abordagem já adotada para conceituar processos, i.e., programas sendo executados pela
CPU, será adotada aos conceitos de subprocessos e threads.
Um algoritmo de escalonamento tem como principal função decidir qual, dentre todos os
processos internos ou externos aos sistema operacional, e que estão na fila de “prontos” para
execução, qual deles será executado pela UCP. Cada sistema operacional necessita de um
algoritmo de escalonamento adequado a seu tipo de processamento.
Um tópico fundamental, relacionado ao escalonamento, é o momento certo de tomar as decisões
de escalonar. Claro que há uma variedade de situações nas quais o escalonamento é necessário.
Primeiramente, quando se cria um novo processo, é necessário tomar uma decisão entre executar
o processo pai ou o processo filho. Como ambos os processos estão no estado de “pronto”, essa é
uma decisao normal de escalonamento e pode levar à escolha de um ou de outro - isto é, o
escalonador pode escolher legitimamente executar o pai ou o filho.
Em segundo lugar, uma decisão de escalonamento deve ser tomada ao término de um processo.
Como o processo não pode executar mais (já que ele não existe mais), algum outro processo deve
ser escolhido entre os processos “prontos”. Se nenhum processo estiver pronto, é executado um
processo ocioso, gerado pelo sistema, normalmente denominado idle.
Em terceiro lugar, quando um processo é suspenso para efetuar uma operação E/S, um outro
processo precisa ser selecionado para ser executado, tirando vantagem da CPU “ociosa”.
52
Em quarto lugar, quando ocorre uma interrupção de E/S, pode-se tomar uma decisão de
escalonamento. Se a interrupção vem de um dispositivo de E/S que acabou de fazer seu trabalho,
o processo que estava bloqueado, esperando pela E/S, pode agora ficar pronto para execução. É o
escalonador quem decide se executa o processo que acabou de ficar pronto, se continua
executando o processo atual (que estava executando no momento da interrupção) ou se seleciona
um terceiro processo para executar.
Se um temporizador (system clock) fornece interrupções de hardware periódicamente, o algoritmo
de escalonamento poderá ser ativado à cada interrupção e um uma decisão de escalonamento
pode ser tomada a cada interrupção de relógio ou a cada fração desse tempo. as algoritmos de
escalonamento podem ser divididos em duas categorias quanto ao modo como tratam essas
interrupções. Um algoritmo de escalonamento não preemptivo escolhe um processo para
executar e entao o deixa executando até que ele seja bloqueado (à espera de uma operação de E/S
ou de um outro processo) ou até que ele voluntariarnente libere a CPU. Mesmo que ele execute
por horas, nao será compulsoriamente suspenso. Na verdade, nenhuma decisao de escalonamento
será tomada durante as interrupções do system clock.
Depois que o tratamento da interrupção do system clock termina, o processo que estava
executando antes da interrupção prossegue até acabar. Por outro lado, um algoritmo de
escalonamento preemptivo escolhe um processo e o deixa em execulção por um intervalo de
tempo máximo previamente fixado. Se ainda estiver executando ao final desse intervalo de
tempo, o processo será suspenso e o escalonador escolherá outro processo para ser executado (se
houver algum disponivel). O escalonamento preemptivo requer a existência de uma interrupção
de relógio ao fim do intervalo de tempo para que o controle sobre a CPU seja devolvido ao
escalonador. Se nao houver relógio disponível, o escalonamento não preemptivo será a única
opção.
7.1 Algoritmos de Escalonamento
Para ambientes diferentes são necessários diferentes algoritmos de escalonamento. Essa situação
ocorre porque diferentes áreas de aplicação e, diferentes tipos de sistemas operacionais, tem
objetivos diferentes. Em outras palavras, o que deve ser otimizado pelo escalonador não é o
mesmo para todos os sistemas. e, por isso mesmo, são verificados 3 ambientes diferentes:
1. Lote (batch)
2. Interativo (usuários)
3. Tempo real (aplicações críticas)
Nos sistemas em lote não há em seus terminais, usuários esperando por uma resposta rápida.
Consequentemente, os algoritmos não preemptivos ou preemptivos com longo intervalo de tempo
para cada processo são em geral aceitáveis, o que reduz as alternâncias entre processos,
melhorando a performance geral do sistema.
Em um ambiente com usuários interativos, a preempção torna-se essencial para evitar que um
processo monopolize a CPU e com isso negue serviços aos demais processos. Mesmo que
nenhum processo “deseje” ser executado para sempre, uma falha (bug) no programa pode levá-lo
a impedir indefinidamente que todos os outros executem. A preempção é vital para coibir tal
comportamento.
Em sistemas de tempo real a preempção é, paradoxalmente, desnecessária em alguns casos pois
os processos sabem que não podem executar por muito tempo e em geral se auto-suspendem
rapidamente. A diferença em relação aos sistemas interativos é que os sistemas de tempo real
53
executam apenas programas que visam ao progresso da aplicação como um todo. Os sistemas
interativos são de propósito geral e por isso mesmo podem executar processos arbitrários não
cooperativos e até mesmo processos de finalidade duvidosa.
7.2 Critérios de Escalonamento
7.2.1 Utilização da CPU
Na maioria dos sistemas computacionais é desejável que a CPU permaneça a maior parte do seu
tempo ocupada em algum processo importante. Uma utilização na faixa de até 40% indica um
sistema com uma carga de processamento baixa, ao passo que uma taxa de utilização acima de
80% indica um sistema bastante carregado, próximo da sua capacidade total. Picos de
processamento são comuns em qualquer sistema computacional, entretanto, a contínua utilização
dos recursos computacionais em uma faixa próxima dos 80% pode significar que um upgrade no
hardware e/ou no software pode ser necessário em breve.
7.2.2 Eficiência (Throughput)
A eficiência (throughput) representa o número de processos executados em um determinado
intervalo de tempo. Quanto maior a eficiência, maior o número de processos executados em
função do tempo. A maximização da eficiência é almejada na maioria dos sistemas.
7.2.3 Tempo de Turnaround
Esse é o tempo que um processo leva desde sua admissão no sistema ate ao seu término, levando
em consideração o tempo de espera para alocação de memoria, espera na fila de processos
prontos para execução, processamento na CPU e operações de E/S.
7.2.4 Tempo de Resposta
Em sistemas interativos, o tempo de resposta é o tempo decorrido do momento da submissão de
um pedido ao sistema até a primeira resposta produzida. O tempo de resposta não é o tempo
utilizado no processamento total de uma tarefa, e sim o tempo decorrido até que resposta seja
apresentada. Este tempo, geralmente, é limitado pela velocidade do dispositivo de saída. De uma
maneira geral, qualquer algoritmo de escalonamento busca otimizar a utilização da CPU e o
throughput, enquanto tenta diminuir os tempos de turnaround e de resposta. Dependendo do tipo
do sistema, um critério pode ser mais enfatizado do que outros, como, por exemplo, nos sistemas
interativos, onde o tempo de resposta deve ser mais considerado.O algoritmo de escalonamento
não é o único responsável pelo tempo de execução de um processo. Outros fatores, como o tempo
de processamento e de espera em operações de E/S, devem ser considerados no tempo total da
execução. O escalonamento somente afeta o tempo de espera de processos na fila de prontos.
7.3 Tipos de Escalonamento
7.3.1 Escalonamento First-In First Out (FIFO)
Nesse tipo de escalonamento, o processo que chegar primeiro (first-in) será o primeiro a ser selecionado para execução (first-out). Seu algoritmo de implementação é bastante simples, sendo
necessária apenas uma fila, onde os processos que passam para o estado de prontos entram no seu
final e são escalonados quando chegarem ao início da fila. Nesse esquema, quando um processo
ganha a CPU, ele a utilizará sem ser interrompido. O principal problema do escalonamento do
tipo FIFO é a impossibilidade de se prever quando um processo terá sua execução iniciada, já que
54
isso varia em função do tempo de execução dos demais processos que se encontram na sua frente.
Outro problema é a possibilidade de processos do tipo CPU-bound de menor importância
prejudicarem os processos I/O-bound mais prioritários. Esse tipo de escalonamento é também
conhecido como “o primeiro a chegar é o primeiro a ser servido” (first come, first served).
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.
7.3.2 Escalonamento Shortest-Job-First (SJF)
Esse algoritmo de escalonamento associa cada processo ao seu tempo de execução. Dessa forma,
quando a CPU estiver livre, o processo em estado de pronto que precisar de menos tempo de CPU
para terminar seu processamento será selecionado para execução (shortest-job-first). Esse tipo de
escalonamento favorece os processos que executam programas menores, além de reduzir o tempo
médio de espera em relação ao escalonamento do tipo FIFO. O problema em relação a esse
algoritmo é determinar, exatamente, quanto tempo de UCP cada processo necessitará para
terminar seu processamento. Esse tempo nem sempre é determinado de forma precisa. Em
ambientes de produção, onde os programas executam frequentemente, é possível estimar o tempo
de execução, mas em ambientes de desenvolvimento isso se torna bastante difícil. Tanto o SJF
quanto o FIFO não são algoritmos de escalonamento aplicados aos sistemas de tempo
compartilhado, onde um tempo de resposta razoável deve ser garantido ao usuário, que utilzia o
sistema computacional de forma interativa.
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
7.3.3 Escalonamento Shortest RemainingTime (SRT)
Um outro tipo de escalonamento é o próximo de menor tempo restante (shortest remaining time),
no qual o escalonador sempre seleciona o processo cujo tempo de execução restante seja o menor
deles. O problema com esse tipo de escalonamento é que, de novo, o tempo de execução total
deve ser conhecido e, além disso, se algum processo chegar que demande um tempo menor de
55
processamento do que o processo atual, então esse será suspenso deixando a CPU para o
processo récem chegado. Esse esquema permite que os jobs curtos obtenham um bom
desempenho.
7.3.4 Escalonamento Cooperativo
No escalonamento cooperativo alguma política não-preemptiva deve ser adotada. A partir do
momento que um processo está em execução, este voluntariamente libera a CPU, retornando para
a fila de prontos. Este tipo de escalonamento permite a implementação de sistemas
multiprogramáveis com uma melhor distribuição do uso do processador entre os processos. Sua
principal característica está no fato de a liberação do processador ser uma tarefa realizada
exclusivamente pelo processo em execução que, de uma maneira cooperativa, libera a CPU para
um outro processo. No escalonamento cooperativo, não existe nenhuma intervenção do sistema
operacional na execução do processo, o que pode ocasionar sérios problemas na medida em que
um programa em loop poderá não liberar a CPU, monopolizando-a para si. Os sistemas da
Microsoft, o Windows 3.1 e o Windows 3.11 foram implementados utilizando o conceito de
multitarefa cooperativa. Nestes sistemas, as aplicações verificam uma fila de mensagens
periodicamente, para determinar se existem outras aplicações que desejam a CPU. Caso um
processo não faça essa verificação, os outros processos não terão chance de serem executados até
o término de execução desse processo.
7.3.5 Escalonamento Circular (Round Robin)
O escalonamento circular (round robin) segue um algoritmo implementado para sistemas de
tempo compartilhado, similar ao do FIFO, porém, quando um processo ganha a CPU, há um
tempo máximo contínuo, denominado time-slice ou quantum, para sua utilização. Quando esse
tempo acaba, sem que antes o processo tenha liberado a CPU, este volta ao estado de “pronto”,
dando a vez para outro processo. Dá-se a esse mecanismo o nome de preempção por tempo e a
fila de processos no estado de “pronto” é tratada como uma fila circular. Dessa forma, o
escalonamento é realizado e a CPU é alocada para cada processo presente na fila de “pronto”,
atribuindo a cada um deles um intervalo de tempo determinado pelo valor do quantum, valor esse
que geralmente assume valores na faixa entre 100 e 300 ms.
Através do escalonamento circular, nenhum processo será capaz de monopolizar a CPU. O
tempo máximo alocado continuamente para um determinado processo é igual ao quantum
definido pelo sistema. No caso de sistemas de tempo compartilhado, onde vários usuários
utilizam o sistema computacional de forma concorrente, esse algoritmo é bastante apropriado. A
figura abaixo 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.
56
7.3.6 Escalonamento por Prioridades
O escalonamento circular consegue uma melhor distribuição do tempo da CPU, relativamente aos
escalonamentos nao-preemptivos, porém ainda assim não é capaz de implementar um
compartilhamento igualitário entre os diferentes tipos de processos presentes em um sistema
computacional. Isso se deve pelo fato de o escalonamento circular tratar todos os processos de
uma maneira igual, o que nem sempre é desejável no mundo real.
Para solucionar esse problema, os processos do tipo I/O-bound devem levar alguma vantagem no
escalonamento, compensando o tempo gasto no estado de espera pelo término do I/O. Como
alguns processos devem ser tratados diferentemente dos outros, torna-se necessária a associação
de uma prioridade de execução a cada um deles. Dessa forma, processos de maior prioridade
sao escalonados preferencialmente e , toda vez que um processo for para a fila de “pronto” com
prioridade superior ao do processo em execução, o sistema deverá interromper o processo
corrente, colocando-o no estado de “pronto” e selecionando o de maior prioridade para ser
executado. Esse mecanismo é definido como preempção por prioridade. A preempção por
prioridade é implementada mediante um temporizador (system clock), que interrompe o
processador em determinados intervalos de tempo, permitindo que o escalonador reavalie as
prioridades e, possivelmente, escalone outro processo.
Considerando-se 2 processos distintos, um processo A do tipo CPU-bound e um processo B do
tipo I/O bound nota-se que para distribuir o tempo da CPU de forma igual, deveremos associar ao
processo B uma prioridade superior a do processo A, com o objetivo de compensar seu tipo de
processamento. Todos os sistemas de tempo compartilhado implementam algum esquema de
prioridade, de forma a atribuir maior importância a um processo no momento do escalonamento.
A prioridade é uma característica do contexto de software de um processo, podendo ser estática
ou dinâmica. A prioridade é dita ser estática quando não é modificada durante toda a existência
do processo, o que pode gerar tempos de resposta elevados.Na prioridade dinâmica, a prioridade
do processo pode ser ajustada de acordo com o tipo de processamento realizado pelo processo
e/ou a carga do sistema. Todo o processo, ao sair do estado de espera, poderá receber um
acréscimo à sua prioridade e, assim, os processos do tipo I/O-bound terão mais chance de serem
escalonados, compensando o tempo em que passam no estado de “espera”. De uma forma geral,
foi observado que apesar da maior complexidade, esse algoritmo gera um tempo de resposta mais
apropriado.
A figura abaixo 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 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.
57
7.3.7 Escalonamento por Múltiplas Filas
Como os diversos processos de um sistema computacional podem possuir características de
processamento diferentes, é muito difícil que um único mecanismo de escalonamento atenda
adequadamente a todos os tipos de processo. Uma solução de contorno seria a classificação dos
diferentes processos em função do tipo de processamento realizado e aplicar a cada grupo
mecanismos de escalonamentos diferentes. Com base nisso, o escalonamento por múltiplas filas
(multi-level queues) implementa diversas filas de processos no estado de "pronto”, onde cada
processo é associado exclusivamente à uma delas. Cada fila possui seu próprio algoritmo de
escalonamento em função das características do processo. Nesse esquema, os processos devem
ser classificados, previamente, em função do tipo de processamento, para poderem ser
encaminhados á uma determinada fila. Cada fila possuí uma prioridade è ela associada, que
estabelece quais filas são prioritárias em relação às outras. O sistema só poderá escalonar
processos de uma fila se todas as outras filas de prioridade maior estiverem vazias.
Considere que os processos, em função de suas características, sejam divididos em 3 grupos:
sistema, interativo e batch. Os processos pertencentes ao sistema deverão ser colocados em uma
fila de prioridade superior ao dos outros processos, implementando um escalonamento baseado
em prioridades. Os processos de usuários interativos devem estar em uma fila de prioridade
média, implementando por exemplo o escalonamento round robin (circular). Para os processos
em lote (batch) o mesmo escalonamento circular poderia ser utilizado, só que com uma
prioridade mais baixa que aquela atribuída aos usuários.
7.3.8 Escalonamento por Múltiplas Filas com Realimentação
Na modalidade do escalonamento por múltiplas filas, os processos eram préviamente
classificados para serem associados à uma determinada fila, com uma determinada prioridade. Se
o processo alterar o seu comportamento no decorrer do tempo, aquela abordagem mostra-se falha
visto que o processo não poderá ser redirecionado para uma outra fila mais adequada. Um
mecanismo ideal seria aquele em que o sistema conheça como os diversos processos e o próprio
sistema se comportam ao longo do tempo, ajustando dinamicamente seus tipos de escalonamento.
O escalonamento por múltiplas filas com realimentação (multi-level feedback queues), similar ao
escalonamento por múltiplas filas, implementa diversas filas, onde cada qual tem associada uma
prioridade de execução, porém, nesta abordagem, os processos não permanecem em uma mesma
fila até o término do processamento. Neste escalonamento, o sistema tenta identificar de forma
dinãmica o comportamento de cada processo, ajustando assim suas prioridades de execução e os
mecanismos de escalonamento.
Esse esquema permite que os processos sejam redirecionados entre as filas do sistema, fazendo
com que o sistema operacional implemente um mecanismo de ajuste dinâmico, denominado
mecanismo adaptativo, que tem como objetivo ajustar os processos em função do
comportamento do sistema. Os processos não são previamente associados às filas de pronto, e sim
direcionados pelo sistema entre as diversas filas com base no seu comportamento. Um processo,
ao ser criado, entra no final da fila de mais alta prioridade. Cada fila implementa o mecanismo de
FIFO para o escalonamento. Quando um processo sendo executado libera a CPU, seja por
preempção por prioridade ou por solicitação à um recurso do sistema, ele é reescalonado dentro
da mesma fila. Quando este processo esgotar seu quantum de tempo, ele será redirecionado para
uma fila de menor prioridade (preempção por tempo).
58
O escalonamento de um processo em uma fila só acontece quando todas as outras filas de
prioridades mais altas estiverem vazias. A fila de mais baixa prioridade implementa o mecanisrno
do escalonamento circular. O quantum em cada fila varia em função da sua prioridade. Quanto
maior a prioridade da fila, menor será o seu quantum de tempo. O quantum dos processos não é
então estático uma vez que poderá variar em função da fila de “pronto” na qual ele se encontra.
Essa política de escalonamento atende as necessidades dos diversos tipos de processos. No caso
de processos do tipo I/O-bound, ela oferece um born tempo de resposta, já que esses processos
tem prioridades altas por permanecerem a maior parte do tempo nas filas de mais alta ordem. No
caso de processos CPU-bound, a tendência é de que, ao entrar na fila de mais alta prioridade, o
processo ganhe a CPU, gaste seu quantum de tempo e seja direcionado para uma fila de menor
prioridade. Dessa forma, quanto mais tempo um processo a CPU, mais ele cairá para filas de
menor prioridade. Esse algoritmo apresenta um caráter de generalidade que pode ser aplicado à
qualquer tipo de sistema, entretanto tal generalidade tem um preço alto a ser pago – o overhead
no processamento dos vários processos.
7.3.9 Escalonamento por Fração Justa (Fair Share)
Considerando o caso em que 2 usuários, 1 e 2, onde o usuário 1 inicia 9 processos e o usuário 2
inicia um processo, com altemancia circular ou com prioridades iguais, o usuário 1 obterá 90 por
cento da CPU e o usuário 2 terá somente 10 por cento dela.
Para evitar isso, alguns sistemas consideram a propriedade do processo antes de escaloná-lo.
Nesse modelo, a cada usuário é alocada uma fração do tempo da CPU e o escalonador escolhe os
processos de modo que essa fração seja garantida. Assim, se dois usuários tiverem 50 por cento
da CPU alocada para cada um deles, cada um terá os 50 por cento, nao importando quantos
processos eles tenham gerado.
Como exemplo, imagine um sistema com 2 usuarios, cada qual com 50 por cento do tempo da
CPU prometida a ele. O usuário 1 tem 4 processos, A, B, C e D, e o usuário 2 tem somente um
processo, E. Se for usado o escalonamento circular, uma possível sequência de escalonamento
que cumpra todas as exigências poderá ser a sequência dada abaixo:
A E B E C E D E A E B E C E D E...
Por outro lado, se ao usuário 1 se destinar duas vezes mais tempo de CPU do que para o usuário
2, obterernos:
A B E C D E A B E C D E...
É claro que existem inúmeras outras possibilidades, porém nem todas elas justas.
7.4 Escalonamento em Sistemas de Tempo Real
Sistemas de tempo real são frequentemente utilizados em aplicações de controle de processos.
Sistemas que controlam indústrias, de controle de tráfego aéreo entre outros são exemplos deste
tipo de sistema.Nos sistemas operacionais de tempo real, o fator tempo é crítico. Diferentemente
dos sistemas de tempo compartilhado, onde um pequeno tempo de resposta é desejado, mas não
obrigat6rio, todo processamento em tempo real deve ser realizado dentro de limites rígidos de
tempo ou, caso contrário, todo o sistema poderá ficar comprometido. No escalonamento para este
tipo de sistema não existe o conceito de quantum ou time-slice.
59
O escalonamento é realizado únicamente com base no esquema de prioridades. Para cada
processo é atribuída uma prioridade associada à sua importância dentro do sistema. Esta
prioridade deve ser estática, não devendo ser alterada no decorrer do processamento. O
escalonamento de tempo real deve ser empregue na solução de aplicações onde existam graus de
exigêcia na execução de suas tarefas. Quanto maior a importancia de uma tarefa, maior será sua
prioridade de execução em relação às demais. Dessa forma, é possível implementar níveis de
prioridade entre as tarefas da aplicação, conforme a necessidade na solução de cada problema.
Um sistema de tempo real é aquele no qual o tempo tem uma função essencial. Em geral, um ou
mais dispositivos físicos extemos ao computador geram estímulos, aos quais a CPU deve reagir
apropriadamente a todos eles dentro de um dado intervalo de tempo. Por exemplo, a CPU em um
tocador de CD obtém os bits que chegam do drive, necessitando convertê-los em sinais sonoros
audíveis (também denominado música) em um intervalo crítico de tempo. Se o cálculo que ele
fizer for muito demorado, a música irá soar diferente. Outros exemplos ao sistemas de tempo real
incluem a monitoração de pacientes em UTIs de hospitais, o piloto automático de aeronaves e
robôs de controle em fábricas automatizadas. Em todos esses casos, ter a resposta certa mas tardia
é tão ruim quanto não ter nada.
Sistemas de tempo real são em geral categorizados como tempo real crítico, i.e., há prazos
absolutos que devem ser cumpridos ou, então, como tempo real nao crítico, no qual o
descumprimento ocasional de um prazo, apesar de indesejável, pode ser tolerável. Em ambos os
casos, o comportamento de tempo real é implementado dividindo-se o programa em vários
processos cujos comportamentos são préviamente conhecidos. De modo geral, esses processos
tem vida curta e podem executar em bem menos de um segundo. Quando um evento externo é
detectado, o trabalho do escalonador é escalonar os processos de tal forma que todos os prazos
sejam cumpridos.
Os eventos aos quais um sistema de tempo real pode precisar responder podem ser divididos em
periódicos (ocorrem em intervalos regulares) ou aperiódicos (acontecem de modo imprevisível).
Um sistema pode ter de responder a múltiplos fluxos de eventos periódicos. Dependendo de
quanto tempo cada evento necessite para ser processado, talvez nem seja possivel tratar de todos.
Por exemplo, se houver m eventos periódicos e o evento i ocorrer com período Pi e necessitar de
Ci segundos de CPU para tratar cada evento, entao a carga total a ser tratada será dada pela soma
de todos os tempos Ci dividida pelo seu respectivo período Pi deverá ser menor igual a 1. Um
sistema de tempo real que satisfaça a esse critério é chamado de escalonável.
Considerando-se um sistema de tempo real não crítico com 3 eventos periódicos, com períodos
iguais a 100, 200 e 500 ms, respectivamente. Se esses eventos requererem 50, 30 e 100 ms de
tempo de CPU por evento, nessa ordem, o sistema é escalonável porque 0,5 + 0,15 + 0,2 < 1. Se
um quarto evento, com periodo de 1 s, for adicionado, o sistema permanecerá escalonável desde
que esse evento nao precise de mais de 150 ms do tempo da CPU por evento. Implícito nesse
cálculo está a hipótese de que o custo extra do chaveamento de contexto é tão pequeno que pode
ser desprezado.
Os algoritmos de escalonamento de tempo real podem ser estáticos ou dinâmicos. Os primeiros
tomam suas decisões de escalonamento antes de o sistema começar a executar. Os últimos o
fazem em tempo de execução. O escalonamento estático só funciona quando há informações
prévias e exatas sobre o trabalho necessário a ser feito e os prazos que devem ser cumpridos. Os
algoritmos de escalonamento dinâmico nao apresentam essas restrições.
60
7.5 Escalonamento com Múltiplos Processadores
O mecanismo de escalonamento para sistemas com múltiplas CPUs é bem mais complexo que
com uma única CPU. A abordagem é ainda mais diferenciada quando se trata de sistemas
fracamente acoplados ou fortemente acoplados.
Em sistemas fracamente acoplados, cada CPU faz seu próprio escalonamento localmente. Todo
sistema possui, além da CPU, sua memória principal, seu sistema operacional com seu algoritmo
de escalonamento e sua propria fila de processos prontos para execução. Nos sistemas fortemente
acoplados é possível implementar uma única fila de “pronto” para todas as CPUs. Todos os
processos estão presentes nesta única fila e são escalonados na primeira CPU disponível. Nesta
solução é importante que, para a execução do algoritmo de escalonamento, seja implementada a
exclusão mútua para seu código. No caso de mais de uma CPU se tomar disponível em um
mesmo instante, não poderá haver a possibilidade de um mesmo processo vir a ser ser escalonado
por 2 CPUs diferentes. A exclusão mútua do escalonador pode ser obtida através de mecanismos
como semáforos e monitores, implementados no sistema operacional.
Vale notar que, como a memoria é única para todos os processadores, ela conterá todos os
processos desse sistema computacional, não importando qual processador executará o processo.
61
8. Gerência de Memória / Memória Virtual
8.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.
8.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.
8.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.
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.
62
Sistema
Operacional
registrador
Área livre para
programas do
usuário
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
usuário
do
Área livre
Sub-utilização da memória principal
8.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 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.
63
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
Sistema
Operacional
Cadastramento
Módulo
Principal
4 KB
Área de
Overlay
Impressão
2 KB
1 KB
Área livre
2 KB
Técnica de Overlay
A área de memória deve ser suficientemente grande para comportar o programa principal e o
maior dos segmentos. Caso ainda não seja possível executar o programa, deve-se procurar dividir
o programa em segmentos ainda menores, cabendo ao programador, efetuar essa divisão de forma
lógica-funcional, através de comandos específicos da linguagem de programação utilizada, assim
como a utilização das system calls apropriadas.
A grande vantagem da utilização desta técnica, apesar de trabalhosa, consiste em se poder
executar programas maiores do que a memória principal (RAM) disponível, evitando-se a
utilização da memória secundária (discos etc;).
8.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.
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.
64
Sistema
Sistema
Operacional
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.
Com a 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 abaixo ilustra o particionamento estático de
uma memória e sua fragmentação interna.
Memória Principal
Sistema
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
65
8.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:
a) reunião de todos os blocos livres adjacentes, formando uma grande área livre,
que se transforma em uma nova partição;
b) 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.
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.
8.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.
66
8.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 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.
67
8.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.
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 linker gerar os 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.
68
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.
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. No âmbito do 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
69
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 working-set 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 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.
8.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:
8.10.1 Algoritmo Otimo: 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.
8.10.2 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.
8.10.3 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.
8.10.4 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.
70
8.10.5 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.
8.10.6 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.
71
9. Gerência de Sistemas de Arquivos
9.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:
9.1.1 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.
9.1.2 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.
9.1.3 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 sub-diretórios. O número de
níveis possíveis depende do Sistema Operacional.
9.2 Sistemas de Alocação de Arquivos
9.2.1 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.
9.2.2 FAT32: igual ao FAT no que diz respeito a organização e desempenho, mas pode trabalhar
com partições de até 2TB.
9.2.3 NTFS: NT File System, original da plataforma Windows NT/2000/XP. Opera com uma
estrutura em árvore binária, oferecendo bom grau de segurança e desempenho. Apresenta as
seguintes características:
1) nomes de arquivo com até 255 caracteres, podendo conter maiúsculas, minúsculas e espaços
em branco;
2) dispensa ferramentas de recuperação de erros;
3) bom sistema de proteção de arquivos;
4) criptografia;
5) suporta discos de até 264 bytes.
O UNIX utiliza um 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 controlar os métodos de acesso
aos arquivos. O UNIX utiliza também alguns diretórios padronizados, de exclusividade do
sistema.
9.3 Gerência de Espaço Livre
Há 3 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
72
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.
9.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
73
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.
Nos sistemas baseados no sistema operacional UNIX, como o Linux, os arquivos apresentam a
propriedade de serem protegidos dessa forma. Às vezes, deseja-se que um ou mais arquivos
estejam disponíveis, ao grupo e aos outros usuários, somente para leitura e execução, mas não
para a escrita/alteração do(s) mesmo(s), pelo fato de o desenvolvedor do(s) mesmo(s) ainda estar
trabalhando nele(s). Nesse caso, o proprietário (owner), valendo-se das facilidades de segurança
oferecidas pelo sistema operacional pode proteger seus arquivos da forma que desejar.
O exemplo abaixo ilustra o arquivo TESTE.TXT, totalmente acessível ao seu proprietário
(RWX), para leitura e execução para o grupo (R-X) e somente para execução para os outros (--X).
Vale lembrar que as letras R, W e X estão associadas respectivamente às operações de
Read(leitura), Write(escrita) e eXecute (execução).
TESTE.TXT
RWX R-X --X
74
10. Exemplos de Sistemas Operacionais
São dados abaixo algumas informações sobre alguns dos sistemas operacionais mais comuns.
Numa rápida cronologia dos principais sistemas operacionais que deixaram sua marca nas últimas
décadas, temos os seguintes eventos:
1969: Nascimento do Unix;
1976: Apple Primeiro micro computador pessoal;
1981: IBMPC Micro computador pessoal de arquitetura aberta;
1985: Macintosh Interface Gráfica;
1990: Windows 3.0 – Ambiente gráfico para o DOS;
1991: Linux – Sistema operacional de código fonte aberto;
1993: Windows NT: Sistema operacional gráfico e desvinculado do DOS
A Apple, que introduziu quase todas as novidades em micro computadores pessoais, não
conseguiu transformar suas idéias em grande participação de mercado, em parte por manter o
monopólio sobre sua plataforma. Atualmente a Apple continua inovando, e o seu sistema MacOS
X usa um núcleo FreeBSD (Unix) por baixo da primorosa interface gráfica, que confirma mais
uma vez a tendência recente de adoção generalizada do padrão de núcleo de sistema operacional
Open Source.
Por outro lado, a IBM sofreu uma concorrênccia pesada dos clones (IBM PC compatible) por ter
aberto a arquitetura do seu PC, mas foi justamente isso que permitiu a popularização do
computador pessoal devido à redução do preço. No mercado do computador pessoal quem mais
lucrou foi a Microsoft com o Windows e a Intel com sua linha de processadores x86.
Numericamente, ambos têm hoje algo em torno de 90% desse mercado.
Já no caso do sistema servidor de médio e grande porte a história tem sido diferente, e desde o
final dos anos 1980, a plataforma predominante tem sido o RISC sob Unix, em um mercado
dividido entre vários fabricantes. Entre os mais polulares sistemas operacionais estão DOS,
Windows, OS/2, Unix e Linux. Dessa lista, alguns não são mais usados, porém foram escolhidos
por razões históricas e/ou didáticas.
10.1 DOS (Disk Operating System)
O conceito DOS (Disk Operating System) teve sua origem nos anos 1960 como uma variação de
TOS (Tape Operating System), e foi usado nos mainframes IBM System/360. Nessa máquina o
sistema operacional era o OS/360 e podia ser instalado em disco, e nesse caso também era
chamado de DOS/360 para diferenciar de TOS/360 (na fita). A história do DOS no IBM-PC se
inicia em 1978 quando a Intel lançou o seu processador 8086 que é o primeiro de 16 bits. Logo na
seqüência, a IBM anunciou que lançaria o seu computador pessoal (IBM-PC) com o processador
8086. Este novo computador necessitava de um sistema operacional, e o mais próximo que existia
à época era o CP/M (Control Program for Microprocessors) da Digital Research que era
executado nos processadores Z80 (Zilog) e 8080/85 (Intel), que são de 8 bits. E do Zilog Z80
pode-se dizer que foi o processador de 8 bits mais popular na sua época, além de ser compatível
com o 8080.
À época, a Digital Research prometeu uma versão do CP/M para o 8086, porém posteriormente a
IBM desistiu do 8086, que foi substituído pelo 8088. E isso tirou momentaneamente a chance de
a Digital Research fornecer o sistema operacional em tempo para o lançamento do IBM-PC.
Aproveitando a lacuna deixada pela Digital Research, Jim Paterson da Seattle Computer Products
75
criou rapidamente um sistema operacional baseado no CP/M, que foi chamado de Q-DOS (Quick
and Dirty Operating System, em alusão ao número de bugs no código) e que rodava no 8088.
Posteriormente, o QDOS foi rebatizado para 86DOS. O lançamento do IBM-PC ocorreu em 1981
com o processador Intel 8088, que é idêntico ao 8086 exceto quanto ao BUS (barramento), que
foi reduzido para 8 bits para reduzir o preço. Ou seja, o 8088 internamente é de 16 bits, porém o
barramento externo é de 8 bits. Para o lançamento do IBM-PC, a Microsoft que nessa época ainda
era uma pequena empresa desenvolvedora de software – comprou todos os direitos do Q-DOS da
Seattle Computer Products.
Foi a partir do Q-DOS que a Microsoft atendeu à requisição da IBM e forneceu o PC-DOS para
equipar essa nova máquina. Podese considerar que o precursor do DOS no IBMPC foi o CP/M da
Digital Research, porém sem esquecer das influências e contribuições do Unix e de outros
sistemas operacionais usados à época. Numa análise mais rigorosa, podemos até afirmar que o
QDOS foi uma imitação do CP/M.
Comercialmente o DOS inicialmente foi disponibilizado ao mercado de duas formas: PC-DOS,
embutido nos equipamentos fabricados pela IBM, e MS-DOS, vendido pela Microsoft para os
demais fabricantes de hardware IBM-PC compatíveis (clones). Do ponto de vista técnico, a
diferença entre PC-DOS e MS-DOS era muito pequena. Convém notar que, à medida que os
clones do IBMPC foram dominando o mercado, o MS-DOS foi alavancado à uma condição de
plena popularidade.
10.2 UNIX
Precursor de muitos sistemas operacionais, o UNIX comegou a ser desenvolvido por volta dos
anos 1960, resultante de um projeto conjunto da AT&T, Honeywell, GE e o MIT (Massachussets
Institute of Techonology), batizado de MULTICS (Multiplexed Information and Computing
Service).
Tratava-se de um sistema modular, montado em uma bancada de processadores, memórias e
equipamentos de comunicação de alta velocidade para aquela época. Pelo projeto original, partes
do computador poderiam ser desligadas para manutenção, sem que outras partes ou os usuários
fossem afetados. No entanto, devido aos atrasos no cronograma do projeto, a AT&T decidiu
abandoná-lo em 1969, mas o MIT continuou trabalhando no seu desenvolvimento. Nesse mesmo
ano, alguns pesquisadores que haviam trabalhando no projeto do MULTICS se uniram para
desenvolver um outro projeto na Bell Laboratories, surgindo em 1971 a primeira versão do Unix.
Inicialmente, o Unix foi utilizado em máquinas da DEC (Digital Equipment Corporation) e em
mainframes. Mas em 1973 o Unix foi reescrito em linguagem C, mantendo apenas uma pequena
parte do núcleo escrita em linguagem Assembly. A parte desenvolvida em linguagem C permitiu
sua portabilidade para outras arquiteturas de computador e a parte em Assembly teve que ser
reescrita para C ou para a linguagem Assembly da outra CPU.
O Unix começou a se popularizar a partir de 1975, quando foi lançada a versão V6, a primeira
disponibilizada fora dos domínios da Bell Laboratories. Nessa época, a Universidade de Berkley
(EUA) comprou os códigos fontes do Unix, possibilitando aos alunos realizarem modificações no
sistema. Em 1979 o Unix foi portado para máquinas VAX, da DEC, e a partir de 1992 foi
adaptado para a arquitetura RISC, como as da HP, Sun, IBM, DEC, entre outras.
76
A partir dos anos 1980 diferentes fabricantes de Unix começaram a divergir das características
iniciais do sistema e então foi criado o comitê POSIX (Portable Operating System Unix) que
especificou todas as características que um sistema operacional devia possuir para pertencer ao
padrão Unix. Desde então tornou-se técnicamente mais correto tratar o Unix como uma família de
sistemas operacionais, ou seja, considera-se membro dessa família todo sistema operacional que
apresentar determinadas características na interface e conjunto de biblioteca de sistema.
Atualmente existem cerca de 30 "sabores" de Unix e alguns exemplos importantes dessa grande
família são SunOS (Solaris), HPUX, AIX, BSD, FreeBSD e Linux. Atualmente, o Unix é popular
nas universidades, institutos de pesquisa e nos CPDs do ambiente corporativo, rodando
principalmente sob a arquitetura RISC e atendendo às empresas de médio e grande porte. As
exceções são Linux e FreeBSD, que lentamente estão conquistando também o segmento desktop.
10.3 OS/2
Antes de partir para o desenvolvimento do Windows, a Microsoft lançou em 1986, em conjunto
com a IBM, as primeiras versões do sistema operacional OS/2. Mas a partir de 1990 as duas
empresas optaram por seguir caminhos separados. Lançada no primeiro semestre de 1992, a
versão 2.0 apresentava uma série de recursos de compatibilidade, entre os quais a possibilidade de
rodar programas do Windows e do DOS, além de adotar a tecnologia de 32 bits que aproveitava
melhor a potencialidade dos IBM-PCs 386, que eram executados por CPUs da Intel.
A interface do OS/2 era muito semelhante à do Windows 95, apresentando área de trabalho
composta por janelas e ícones. Em 1992, a IBM lançou o OS/2 WARP, que integrava a
tecnologia orientada a objeto. Porém, o OS/2 não vingou tanto pela carência de aplicações quanto
por ser muito "pesado" para os computadores da época. É fato que a parceria da Microsoft no
desenvolvimento do OS/2 influenciou na posterior concepção do Windows NT, que também
contou em seu time de projetistas para esse novo sistema operacional, experientes
desenvolvedores de software e de sistemas operacionais, em particular, egressos da Digital
Equipment Corporation que haviam trabalhado no desenvolvimento do sistema operacional Open
VMS.
10.4 Windows
Em 1985 a Microsoft lançou a primeira versão do Windows, que não era sistema operacional mas
sim interface gráfica que rodava sobre o DOS. Em novembro de 1987 veio a versão 2.0, que ao
contrário da versão 1.0, era capaz de sobrepor janelas. Foi na versão 2.0 que vieram pela primeira
vez as aplicações Word e Excel para Windows, porém de início não foram sucesso quando
comparadas com suas versões para DOS, de linha de comando.
O Windows começou a fazer sucesso na versão 2.1, mas ficou popular mesmo a partir da versão
3.0, disponibilizada em 1990, já relativamente leve mesmo para os PCs mais básicos da época. A
versão 4.0 do Windows, conhecida como Windows 95, foi disponibilizada ao mercado em 1995 e
rapidamente tornou-se um dos sistemas operacionais mais populares devido a sua facilidade de
uso, compatibilidade e principalmente devido à grande disponibilidade de software aplicativo que
era executado nese sistema. Embora fosse um sistema multitarefa e com estrutura de 32 bits,
grande parte do seu código era baseado no Windows 3.11.
Para o ambiente corporativo foi desenvolvido o NT (New Technology), que foi o primeiro sistema
operacional de 32 bits da Microsoft. A primeira versão do NT foi a 3.1, de 1993, e que tinha a
aparência da interface gráfica do ambiente operacional Windows 3.1. Ao longo da sua história o
Windows, basicamente, passa por 3 fases distintas:
77
● Fase 1 (1985 a 1995): É ambiente gráfico sobre o DOS. As versões vão da 1.0 até 3.1;
● Fase 2 (1995 a 2000): O DOS está "embarcado" (embutido) no ambiente gráfico. As versões
vão da 4.0 (Windows95) até 4.9 (Millennium);
● Fase 3 (1993 até hoje): São baseados no NT. O controle de versão é diferente das anteriores,
inicia em 3.1 e atualmente está em 5.2 (Windows 2003 Server).
É da Fase 3 a origem dos atuais sistemas Windows2000, XP e 2003 Server, que são sistemas
operacionais gráficos e não tem mais nenhuma relação com o DOS. Estes sistemas são ditos
"baseados no NT". Outra diferença é que a FASE 3 já inicia em 32 bits, ao contrário das
anteriores que sempre mantiveram pelo menos alguma relação original com os 16 bits.
Outro aspecto interessante está relacionada à multitarefa no Windows, na Fase 1 é cooperativa
pois o Windows é ambiente gráfico que é executado sobre o DOS. Nas demais fases já é
multitarefa real ou preemptiva. Na multitarefa cooperativa as aplicações para Windows precisam
cooperar para garantir a multitarefa, na preemptiva os processos são escalonados e cada um
recebe determinado tempo de CPU.
Uma análise das versões do Windows desde o lançamento em 1985 até hoje (ver tabela abaixo),
evidencia uma nítida seqüência evolutiva. Porém, é importante notar que a linha atual nasce com
a versão NT 3.1 de 1993, enquanto a linha original (baseada no DOS) é descontinuada em 2000.
78
10.5 Windows NT
O desenvolvimento do Windows NT iniciou em 1988, após a Microsoft contratar um grupo de
programadores experientes que veio da Digital Equipment Corporation (DEC). O projeto foi
conduzido por David Cutler, também ex projetista da DEC. A intenção inicial do projeto NT era
ser a nova versão do OS/2, versão 3.0, desenvolvida em parceria com a IBM. Porém, o grande
sucesso do Windows 3.0 de 1990 encorajou a Microsoft a seguir seu próprio rumo, isso após
romper a parceria no desenvolvimento do OS/2.
O projeto NT deveria contemplar sistemas servidores e estações de trabalho totalmente 32 bits
para o ambiente corporativo em redes de computadores, e foi considerado ambicioso na medida
em que podia ser utilizado em arquiteturas de computador desenvolvidas por diferentes
fabricantes, como as da Digital (Alpha), IBM (Power PC), Intel (Pentium), Silicon Graphics
(MIPS), entre outros. O objetivo da Microsoft era desenvolver um sistema operacional multitarefa
para ser utilizado tanto em ambientes monousuário como multiusuário. O NT também se
caracterizaria por ser compatível com o sistema operacional MSDOS.
O lançamento do NT ocorreu em 1993 e contemplou versões para servidores e para estações de
trabalho, além de ser multiplataforma e de fato totalmente 32 bits. O nome Windows NT vem de
New Technology, escolhido de propósito para descolar do antigo Windows 3.1 que, por rodar
sobre o DOS, apresentava um número muito grande de problemas e jamais poderia ser imaginado
como servidor de rede.
Surpreendentemente, na escolha da versão inicial para o NT foi invocada a versão do Windows
3.1. Inclusive, a primeira versão do NT tinha a interface gráfica do Windows 3.1 e não mais a
original do OS/2. Logo na seqüência, a versão 4.0 alterou essa interface para ser igual a do recém
lançado Windows 95.
A proposta inicial do NT era ofertar estações de trabalho suficientemente confiáveis e
competitivas a ponto de serem adotadas em larga escala nos diversos ambientes corporativos,
além do servidor de rede para atender a essas estações. Na versão 3.1 do NT havia apenas
workstation e server, mas posteriormente nas novas versões essas subdivisões foram aumentando,
conforme poderá ser visto na tabela abaixo.
A diferença básica entre workstation e server estava no modo de operação (cliente e servidor),
nos serviços oferecidos e aos segmentos para os quais cada um deles foi desenvolvido, além do
número de processadores suportados.
Como pode ser visto na tabela 4, abaixo, tanto o NT 5.0 quanto NT 5.2 oferecem 4 subdivisões
que indicam uma maior diversificação da linha quando comparados como o NT 3.1. Essa
diversificação ocorre para melhor atender aos diferentes segmentos de servidores dos ambientes
corporativos, diversificação essa que aparentemente continuará a aumentar nas futuras versões
caso continue a boa aceitação do Windows nesse segmento.
É válido observar que a partir do NT 5.2 o conceito original de estação de trabalho wokstation,
que passou a ser chamado de professional no NT 5.0, passa a ter uma linha independente baseada
no XP.
79
Da tabela acima pode ser notado que o NT 5.2 oferece também versões verdadeiramente de 64
bits quando estiver sobre a arquitetura EPIC. A linha de processadores da Intel (x86) atualmente
ainda está nos 32 bits. Porém, devido à necessidade de endereçamento de memória além dos 4
GB, a partir do Pentium Pro seus chips incorporam a tecnologia PAE (Intel Physical Addressing
Extensions), que permite endereçar até 64 GBytes de memória RAM numa CPU de 32 bits. A
tecnologia PAE extende para 36 bits o endereçamento de memória, mas para que o sistema
operacional lance mão dessa solução é necessário também suporte no chipset (placa mãe).
Num caso típico de estação de trabalho Windows, raramente se torna necessário ir além de
poucos gigabytes de memória, porém num sistema servidor mesmo de médio porte é
imprescindível ir bem além do limite de 4 GB imposto pela arquitetura de 32 bits. E tendo em
vista a necessidade de permitir maior alocação de memória para servidores baseados no x86, a
Intel lançou também a extensão de 64 bits. Essa é a tecnologia EM64T (Extended Memory), que é
uma extensão de 64 bits para a alocação de memória numa CPU de 32 bits. Como produtos, estão
o P4 (Pentium 4) e Xeon, que são CPUs típicas em servidores baseados em CISC.
No entanto, ao contrário do PAE, a tecnologia EM64T não está disponível em toda a linha de
CPUs, mas apenas naquelas destinados ao segmento de servidores. Antes de a Intel lançar a
tecnologia EM64T, a AMD, concorrente da Intel, já tinha essas extensões na sua arquitetura
X8664.
Outra conclusão importante a partir da tabela acima, é que com o EPIC (Itanium) o NT 5.2
finalmente chegou aos 64 bits e voltou a ser multiplataforma. No lançamento do NT (1993) havia
o suporte a RISC, que posteriormente foi retirado. A geração dos sistemas operacionais Windows
XP (NT 5.1) foi idealizada com o objetivo de unificar em torno de um único produto o mercado
corporativo e o de usuários domésticos.
80
Nesse sentido foram desenvolvidas 2 versões:
● Windows XP (eXPerience) Personal Edition, voltado para o mercado doméstico e com a
proposta de substituir os Windows 9.X, Millennium e NT Workstation;
● Windows XP Professional Edition, para o mercado corporativo e cuja proposta original era
substituir o NT inclusive nas versões server. Sabe-se hoje que o XP server não vingou, e que em
seu lugar veio o Windows 2003 Server (NT 5.2). Desse modo, as 4 subdivisões do NT 5.2
apresentadas na tabela 4 são todas de sistemas operacionais servidores. Já o NT 5.0 também tem 4
subdivisões, porém uma delas é o Windows 2000 professional que é estação de trabalho, desse
modo confirmando mais uma vez o aumento na diversificação da linha NT a cada nova versão.
10.6 Linux
Originalmente escrito por Linus Torvalds, do Departamento de Ciência da Computação da
Universidade de Helsink, na Finlândia e, contando com a colaboração de vários programadores
voluntários que trabalharam em conjunto através da Internet, o Linux teve sua primeira versão
oficial lançada em 5 de outubro de 1991. O sistema foi desenvolvido como um hobby por
Torvalds que se inspirou no Minix, o mini sistema Unix desenvolvido por Andrew Tanenbaum.
81
11.0 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
82
12.0 Dicionário de Termos (Glossário)
Algoritmo: dá-se o nome de algoritmo à uma sequência de passos ou ações necessárias para que
algo determinado e esperado aconteça. Algoritmos podem ser escritos ou não em uma
metalinguagem, como por exemplo, as instruções contidas em receitas de bolos, torta, doces etc.
Um algoritmo pode também ser escrito em uma determinada linguagem de programação, como
por exemplo Java, VB, C, C++ etc.
APM : é a sigla para Advanced Power Management, uma norma de gerenciamento de energia
usada inicialmente em computadores portáteis (laptop), mas que mais tarde foi adotada também
nos computadores de mesa (desktop). A sua principal função é controlar diversos componentes do
sistema de modo a ativar modos de poupança de energia quando não estão a ser utilizados.
Recentemente esta tecnologia vem sendo substituída pela norma ACPI, que não se limita somente
à gestão do consumo de energia.
ACPI : a ACPI (Advanced Configuration and Power Interface) é um padrão desenvolvido pela
HP, Intel, Microsoft, Phoenix e Toshiba para configuração e gerenciamento de energia do
computador. A ACPI tem como proposta suplantar o APM; enquanto a primeira coloca o sistema
operacional no controle do gerenciamento de energia, o APM usa o BIOS para isso. A
implementação da ACPI depende não apenas de software, mas também de hardware compatível.
Este padrão prevê atualmente os seguintes estados energéticos :
Sub-estados de energia globais
G3 : Mechanical Off (desligado mecanicamente).
G2 : Soft Off (desligado por software) — existe uma corrente elétrica mínima e não é seguro
desmontar o equipamento. Este estado pode também ser denominado S5.
G1 : Sleeping ("dormindo") — o computador parece desligado mas quando ele "acorda" (wake) o
sistema operacional não precisa ser reiniciado.
G0 : Working (“ em funcionamento”) — apesar de o computador estar ligado, os periféricos
podem estar em estados variáveis de conservação de energia.
Sub-estados do modo sleeping
As especificações da ACPI não dão nome específicos aos estados abaixo listados, de forma que
vários nomes são usados para a mesma coisa, e às vezes um mesmo nome é usado em sentidos
diversos.
S1 : Baixa conservação de energia, sem a perda do contexto no qual a CPU está trabalhando.
S2 : Semelhante ao S1, mas o contexto da CPU é perdido, e o sistema operacional é responsável
por reestabelecer esse contexto quando a máquina "acordar".
S3 : A memória RAM continua recebendo energia, mas não a CPU e o cache de memória.
Quando o sistema "acorda", a informação armazenada na RAM é utilizada para reestabelecer o
estado prévio. No Windows esse estado é denominado de "modo de espera" e e "Suspender para
RAM" em outros sistemas.
S4 : Nem a memória RAM recebe energia e quando o computador "acorda", o estado prévio é
recuperado através de informações armazenadas no disco rígido. Conhecido como "hibernar" no
Windows e "Suspender para o disco" em outros sistemas operacionais.
83
Sub-estados do modo Working
C0 : Processando informações
C1-3 : Inativo, mas reativados no caso de instruções, com latência progressivamante maior.
Sub-estados associados aos dispositivos
D3 : Off (desligado).
D2-1 : Estados intermediários; especificação depende do tipo de dispositivo.
D0 : Fully-On (“energizado (ou ligado”)).
Para dispositivos em D0 e processadores em C0, é possível especificar dois ou mais níveis de
consumo de energia sendo P0 o estado de maior gasto. No caso dos processadores, a Intel chama
essa tecnologia de SpeedStep e a AMD de Cool'n'Quiet
Barramento (Bus) : barramento é um conjunto de linhas de comunicação que permitem a
interligação entre dispositivos, como o CPU, a memória e outros periféricos, de forma a permitir
a comunicação entre esses elementos. Ele também pode ser visto como um conjunto de sinais
(linhas) que viabilizam a comunicação entre os demais módulos. Distinguem-se, pelo menos, 3
tipos de linhas: de dados, de endereços e de controle. Podemos assumir que, enquanto um par de
módulos dialoga através do barramento, um árbitro de barramento (o bus controller) garante que
nenhum outro par seja capaz de fazê-lo simultaneamente. O barramento interliga diversas CPUs,
a memória principal e as controladoras dos periféricos. A memória é considerada global, visível a
todas as CPUs e controladores de periféricos, assim como os próprios periféricos.
Este barramento, também denominado de barramento central, pode ser sub-dividido em 3
conjuntos:
1) barramento de dados: onde trafegam os dados;
2) barramento de endereços: onde trafegam os endereços;
3) barramento de controle: sinais de controle que sincronizam os barramentos de dados e de
endereços.
O desempenho do barramento é medido pela sua largura de banda (quantidade de bits que podem
ser transmitidos ao mesmo tempo), normalmente expressos em potências de 2, ou seja 8 bits, 16
bits, 32 bits, 64bits, 128 bits e assim por diante, assim como também pela velocidade da
transmissão medida em bps (bits por segundo), como por exemplo 10 bps, 160 Kbps, 100 Mbps,
1 Gbps etc. É através do barramento que o processador faz a comunicação com o seu exterior.
Nele trafegam os dados lidos da memória, escritos na memória, enviados para interfaces e
recebidos de interfaces.
São exemplos de barramentos centrais os seguintes tipos de barramentos: AGP ; AMR ; EISA ;
FireWire ; IrDA ; ISA ; MCA ; PCI ; PCI Express ;Pipeline ; VESA Local Bus ; USB ; PS/2 etc.
Nas CPUs mais modernas, com arquiteturas mais recentes, há um barramento interno à própria
CPU que pode ser sub-dividido em três grupos:
a)barramento de cache : o barramento em cache, existente em arquiteturas de computadores
mais recentes, é um barramento dedicado para acesso à memória cache do computador.
84
b)barramento de memória : o barramento de memória é responsável pela conexão da memória
principal ao processador. É um barramento de alta velocidade que varia de CPU para CPU e
atualmente gira em torno de 533MHz a 1333MHz.
c)barramento de Entrada e Saída : o barramento de E/S é um conjunto de circuitos e linhas
de comunicação que se ligam ao resto do computador com a finalidade de possibilitar a expansão
de periféricos e a instalação de novas placas. Permitem a conexão com dispositivos tais como
placa gráficas ; placas de rede ; placas de som ; mouse ; teclado ; modem etc.
Compilador: dá-se o nome de compilador ao utilitário que aceita como entrada um arquivo fonte
(arquivo texto) escrito em uma determinada linguagem de programação e gera como saída um
arquivo objeto, pronto para ser transformado em um arquivo executável pelo linker. Como
exemplos de compiladores temos os compiladores Fortran, Pascal, Cobol, C etc.
Cotas em disco: o regime de cotas em disco foi incorporado ao kernel de alguns sistemas
operacionais (Windows, Linux etc.) e ao subsistema de gerenciamento de discos. Nesse regime,
existe a opção dos administradores de definirem o quanto de espaço em um determinado disco
cada usuário pode ocupar.
Cotas de tempo : para cada processo é atribuído uma cota de tempo para que este possa ser
executado pela CPU. Isso impede que um processo obtenha todo o tempo da CPU para si próprio.
Para sistemas do tipo monotarefa (monotask), como o antigo DOS (Disk Operating System), isso
não representa problema algum, mas para sistemas do tipo multitarefas (multitask), como por
exemplo o UNIX, o QNX, o Open VMS, o Linux e assemelhados, além do próprio MS-Windows,
isso é algo que não pode acontecer, visto que todos os outros demais processos, incluíndo-se aí os
vários processos do próprio sistema operacional, podem não ser mais executados, levando o
sistema a uma situação de erro insustentável.
Deadlock (abraço mortal, impasse) : no contexto do sistemas operacionais o deadlock
caracteriza uma situação em que ocorre um impasse e 2 ou mais processos ficam impedidos de
continuar suas execuções, ou seja, ficam bloqueados. Trata-se de um problema bastante estudado
no contexto dos Sistemas Operacionais, assim como em outras disciplinas, como banco de dados,
pois é inerente à própria natureza desses sistemas. O deadlock ocorre com um conjunto de
processos e recursos não-preemptíveis, onde um ou mais processos desse conjunto está
aguardando a liberação de um recurso por um outro processo que, por sua vez, aguarda a
liberação de outro recurso alocado ou dependente do primeiro processo, criando uma cadeia de
esperas.
No entanto, algumas observações são pertinentes:



o deadlock pode ocorrer mesmo que haja somente um processo no SO, considerando que
este processo utilize múltiplas threads e que tais threads requisitem os recursos alocados
a outras threads no mesmo processo;
o deadlock independe da quantidade de recursos disponíveis no sistema;
normalmente o deadlock ocorre com recursos como dispositivos, arquivos, memória etc.
Apesar da CPU também ser um recurso para o SO, em geral é um recurso fácilmente
85
preemptível, pois existem os escalonadores para compartilhar o processador entre os
diversos processos, quando trata-se de um ambiente multitarefa.
Debugger (depurador): o desenvolvimento de programas está sujeito a muitos erros de lógica,
independentemente das metodologias ou linguagens de programação utilizadas pelo
programador. A depuração é um dos estágios desse desenvolvimento, e a utilização de
ferramentas adequadas é essencial para acelerar o processo de desenvolvimento e correção dos
programas. Nesse contexto, o depurador (debugger) é o utilitário que permite ao usuário
controlar toda a execução de um programa a fim de detectar erros na sua estrutura. Este utilitário
oferece ao usuário uma grande gama de recursos tais como:
1) acompanhar a execução de um programa instrução por instrução (step by step);
2) possibilitar a alteração e visualização dos conteúdos das variáveis utilizadas no programa;
3) implementar pontos de parada dentro do programa, também conhecidos por breakpoints, de tal
forma que, durante a execução do programa, o programa pare nesses pontos;
4) especificar condições de teste diversas, baseadas nos conteúdos de uma ou mais variáveis
5) enviar mensagens específicas sobre acontecimentos que o usuário deseje acompanhar
Hardware: apesar de a palavra hardware poder ser aplicada para tudo aquilo que é material, no
sentido físico da palavra, atualmente, ela é empregada para denotar todo e qualquer dispositivo
eletrônico ou eletro-mecânico encontrado nos computadores, sejam eles de uso pessoal (PC) ou
não, como por exemplo, os grandes computadores, também conhecidos por mainframes, sejam
eles de uso científico ou não. Exemplos de hardware são as placas mães (motherboards), os
discos magnéticos ou óticos, a CPU, impressoras, scanners, webcams etc
Interpretador: dá-se o nome de interpretador ao utilitário que aceita como entrada um arquivo
fonte (arquivo texto) escrito em uma determinada linguagem de programação e gera como saída
um arquivo intermediário, que será posteriormente lido e executado por um outro programa. Esse
código intermediário pode ser copiado para outra máquina que contenha esse interpretador sem
que seja necessário uma nova interpretação. Exemplos de interpretadores são os da linguagem
PERL, PHP e Java. O interpretador Java gera um arquivo do tipo .CLASS que pode ser executado
em qualquer máquina que contenha o JVM e o JRE dentre outros requisitos. No jargão do
“mundo” Java, dá-se o nome de bytecodes ao código intermediário produzido pelo interpretador
Java.
JCL (Job Control Language): A linguagem de controle, também denominada linguagem de
comando, é a forma mais direta de um usuário se comunicar com o sistema operacional. Esta
linguagem é oferecida por cada sistema operacional e, portanto, diferem entre si. Valendo-se dos
recursos oferecidos pela JCL, através de comandos relativamente simples, o usuário pode ter
acesso à rotinas específicas do sistema operacional. Esses comandos, quando fornecidos e
digitados pelos usuários, são interpretados por um outro programa denominado interpretador de
comandos ou simplesmente shel). O interpretador reconhece a linha de comando, verifica sua
sintaxe, envia mensagens de erro e faz chamadas a rotinas do sistema. Dessa forma, o usuário
dispõe de uma interface interativa com o sistema operacional, para realizar tarefas como acessar
arquivos em disco, consultar diretórios e sub-diretórios, assim como acessar dados referentes à
cada arquivo existente no computador tais como, data de criação, última data de alteração ou de
leitura, atributos quando da sua criação etc.
86
Algumas linguagens de controle são tão poderosas e práticas que chegam a oferecer a
possibilidade de serem criados programas com estruturas de decisão e iteração, podendo o
usuário interagir com tais programas, que são conhecidos também por scripts. Esses programas
nada mais são do que uma sequencia de comandos JCL armazenadosob a forma de arquivo
(arquivo de comandos), que podem ser executados sempre que necessário. As linguagens de
controle evoluiram tanto que algumas delas chegam a interfaces graficas para a comunicação
com o usuário.
Linguagem de Máquina: A linguagem de máquina de um computador é a linguagem de
programação que a CPU realmente consegue executar. Cada modelo de CPU possui um conjunto
único de instruções de máquina, definido pelo proprio fabricante. As instruções especificarn
detalhes tais como quais registradores podem ser utilizados para funções específicas ou não, seus
modos de endereçamento e tipos de dados, que caracterizam uma CPU e suas potencialidades .
Um programa em linguagem de máquina é total mente expresso (codificado) em formato binário,
ou seja em uma sequência de “1”s e “0”s, o que torna o seu entendimento, para nós humanos,
muitíssimo mais confuso e tedioso, por ser essa linguagem totalmente voltada para a CPU.
Programas expressos em linguagem de máquina podem ser diretamente processados pela CPU,
nao requerendo qualquer tipo de tradução ou relocação. Um programa escrito em linguagem de
máquina para um determinado modelo de CPU normalmente não pode ser executado em outra
CPU de modelo diferente. Isso acontece porque o conjunto de instruções de uma maquina é
caracteristica de cada CPU. Nos últimos anos isso deixou de ser algo impactante como por
exemplo nos casos reais envolvendo algumas CPUs da Intel e da AMD e da Intel com a Zilog.
Linker: dá-se o nome de linker ao programa que aceita como entrada um arquivo objeto, gerado
por um compilador, e atribui os endereços de memória referenciados pelo programa e necessários
à execução desse programa pela CPU.
Loader: é também chamado de carregador. È o utilitário responsável por colocar fisicamente na
memória um programa para ser executado. O procedimento de carga varia com o c6digo gerado
pelo linker e, em função deste, o loader é cIassificado como sendo do tipo absoluto ou relocável.
Se o código executável tiver sido gerado como sendo do tipo absoluto, o loader só necessita
conhecer o endereço de memória inicial e o tamanho do módulo para realizar o carregamento.
Então o loader lê o programa a ser executado da memória secundária (disco, CD etc.) para a
memoria principal (RAM) e inicia sua execução. Por outro lado, se o c6digo tiver sido gerado
como sendo do tipo relocável, o programa a ser executado pode ser carregado para qualquer
posição da memória RAM, sendo o loader o responsável pela relocação do código no momento
do carregamento. Por relocação deve-se entender como sendo a atribuição de novos endereços de
memória, disponibilizados pelo sistema operacional, ao programa a ser executado, sem que com
isso haja qualquer prejuízo em relação ao código originalmente gerado.
Memória: dá-se o nome de memória à todo o tipo de elemento capaz de armazenar informações,
sejam elas permanentes ou temporárias. As memórias se dividem em memórias voláteis e nãovoláteis (veja abaixo). Há memórias de acesso aleatório (random) e de acesso sequencial. As
memórias de acesso sequencial são aquelas que tem o maior tempo de acesso, comparativamente
às memórias de acesso aleatório. Exemplos de memórias do tipo sequencial são as fitas
magnéticas (de áudio, videocassete ou de computador) onde, por exemplo, para se ouvir a última
87
música ou recuperar o último registro é necessário esperar até que a cabeça de leitura chegue ao
final da fita, o que pode demandar bastante tempo.
A memória pode ser vista como um conjunto de posições seqüenciais, univocamente identificadas
por endereços, onde à cada posição de memória corresponde um endereço. Cada posição de
memória é denominada uma palavra e tem seu tamanho dado em bits. Tipicamente, uma palavra
de memória corresponde a 16, 32 ou 64 bits.
Funcionalmente, a memória responde a 2 operações básicas:
a) leitura do conteúdo de uma ou mais palavras consecutivas.
b) escrita de um determinado valor (cujo tamanho em bits pode corresponder a uma ou mais
palavras.
Memórias de acesso aleatório são aquelas em que as informações podem ser obtidas de qualquer
forma, como por exemplo as memórias semicondutoras de um computador, ou uma particular
trilha e setor de um disco magnético ou disco ótico. Para se ouvir, por exemplo, uma determinada
faixa musical de um CD ou de um DVD, o usuário pode fornecer diretamente o número da trilha
(track) onde a música está e ouví-la sem ter que esperar muito tempo.
O tipo de memória conhecido como FLASH é o tipo mais moderno dentre os apresentados aqui,
mas é uma variação do tipo EEPROM. Tornaram-se muito populares por dois motivos: a
utilização de dispositivos de armazenamento removíveis como os chamados pen drives, a
aplicação em equipamentos de som que reproduzem música no formato MP3 e os cartões de
memória das câmeras digitais. Os dados armazenados neste tipo de memória permanecem ali sem
a necessidade de alimentação. Sua gravação é feita em geral através da porta USB que fornece o
nível de tensão (voltagem) e corrente (amperagem) necessárias para alimentação.
As memórias de massa podem armazenar grande quantidade de informação e têm tido seu
tamanho reduzido a cada dia. O disco rígido é o meio mais comum neste tipo de memória, mas os
disquetes ainda ocupam uma pequena parcela do mercado. As memórias de massa não são tão
rápidas como a memória flash mas já podem ser utilizadas em equipamentos de reprodução de
música e filmes como os portáteis que reproduzem videoclipes de música em vários formatos.
Observe abaixo algumas fotos de memórias do tipo semicondutoras:
88
Memória Cache : Na área da computação, cache é um dispositivo de acesso rápido, interno a um
sistema, que serve de intermediário entre um operador de um processo e o dispositivo de
armazenamento ao qual esse operador acessa. A vantagem principal na utilização de uma cache
consiste em evitar o acesso ao dispositivo de armazenamento - que pode ser demorado -,
armazenando os dados em meios de acesso mais rápidos. Memória Cache é uma pequena
quantidade de memória estática de alto desempenho que tem por finalidade aumentar o
desempenho do processador.
Com os avanços tecnológicos, vários tipos de cache foram desenvolvidos. Atualmente há cache
em processadores, discos-rígidos, sistemas, servidores, nas placas-mães, dentre outros exemplos.
Qualquer dispositivo que requeira do usuário uma solicitação/requisição a algum outro recurso,
seja de rede ou local, interno ou externo a essa rede, pode requerer ou possuir de fábrica o recurso
de cache.
Por ser mais caro, o recurso mais rápido não pode ser usado para armazenar todas as informações
e, sendo assim, usa-se a cache para armazenar apenas as informações mais frequentemente
usadas. Nas unidades de disco também conhecidas como disco rígido ou hard disk (HD), também
existem chips de cache nas placas eletrônicas que os acompanham, como por explo, a unidade
Samsung de 160 GB que tem 8 Mbytes de cache.
A memória cache é útil em vários contextos, tais como:
nos casos dos processadores, em que a cache disponibiliza alguns dados já requisitados e outros
ainda “a processar”;
89



no caso dos navegadores, em que as páginas são guardadas localmente para evitar
consultas constantes à rede (especialmente úteis quando se navega por páginas estáticas);
no caso das redes de computadores , o acesso externo , ou à Internet , se dá por meio de
um software que compartilha a conexão ou link , software este também chamado de
proxy , que tem por função rotear as requisições a IPs externos à rede que se encontra ,
nestes proxys temos ainda um cache , que na verdade é uma enorme lista de todos os sites
que foram visitados pelos usuários dos computadores desta rede, fazendo com isto a
mesma função que os caches presentes nos navegadores , ou browsers, só que com a
atribuição de servir a toda a rede e com isso aumentar a taxa de acerto dos proxys ,
minimizar o consumo do link e agilizar a navegação.
os servidores Web, também dispõem de caches configurados pelo administrador, que
variam de tamanho conforme o número de page views que o servidor tem a oferecer.
A memória cache é um bloco de memória para o armazenamento temporário de dados que
possuem uma grande probabilidade de serem utilizados novamente. Uma definição mais simples
de cache poderia ser: uma área de armazenamento temporária onde os dados freqüentemente
acedidos são armazenados para acesso rápido. Uma cache é feita de uma fila de elementos. Cada
elemento tem um dado que é a cópia exata do dado presente em algum outro local (original).
Cada elemento tem uma etiqueta que especifica a identidade do dado no local de armazenamento
original, que foi copiado. Quando o cliente da cache (CPU, navegador etc.) deseja acessar a um
dado que acredita estar no local de armazenamento, primeiramente ele verifica a cache. Se uma
entrada for encontrada com uma etiqueta correspondente ao dado desejado, o elemento da cache é
então utilizado ao invés do dado original. Essa situação é conhecida como acerto do cache (cache
hit). Como exemplo, um navegador poderia verificar a sua cache local no disco para ver se tem
uma cópia local dos conteúdos de uma página Web numa URL particular. Nesse exemplo, a URL
é a etiqueta e o conteúdo da página é o dado desejado. A percentagem de acessos que resultam
em cache hits é conhecida como a taxa de acerto (hit rate ou hit ratio) da cache.
Uma situação alternativa, que ocorre quando a cache é consultada e não contém um dado com a
etiqueta desejada, é conhecida como cache miss (erro do cache). O dado então é copiado do local
original de armazenamento e inserido na cache, ficando pronto para o próximo acesso. Se a cache
possuir capacidade de armazenamento limitada (algo comum de acontecer devido ao seu custo), e
não houver mais espaço para armazenar o novo dado, algum outro elemento deve ser retirado dela
para que liberte espaço para o novo elemento. A forma (heurística) utilizada para seleccionar o
elemento a ser retirado é conhecida como política de troca (replacement policy).
Uma política de troca muito popular é a LRU (least recently used), que significa algo como
“elemento recentemente menos usado”. Quando um dado é escrito na cache, ele deve ser gravado
no local de armazenamento em algum momento. O momento da escrita é controlado pela política
de escrita (write policy). Existem diferentes políticas.
A política de write-through (algo como “escrita através”) funciona da seguinte forma: a cada vez
que um elemento é colocado no cache, ele também é gravado no local de armazenamento
original. Alternativamente, pode ser utilizada a política de write-back (escrever de volta), onde as
escritas não são directamente espelhadas no armazenamento. Ao invés, o mecanismo de cache
identifica quais de seus elementos foram sobrepostos (marcados como sujos) e somente essas
posições são colocadas de volta nos locais de armazenamento quando o elemento for retirado do
cache. Por essa razão, quando ocorre um cache miss (erro de acesso ao cache pelo fato de um
elemento não existir nele) em um cache com a política write-back, são necessários dois acessos à
memória: um para recuperar o dado necessário e outro para gravar o dado que foi modificado no
cache.
90
O mecanismo de write-back pode ser accionado por outras políticas também. O cliente pode
primeiro realizar diversas mudanças nos dados do cache e depois solicitar ao cache para gravar os
dados no dispositivo de uma única vez.
Os dados disponíveis nos locais de armazenamento original podem ser modificados por outras
entidades diferentes, além do próprio cache. Nesse caso, a cópia existente no cache pode se tornar
inválida. Da mesma forma, quando um cliente atualiza os dados no cache, as cópias do dado que
estejam presentes em outros caches se tornarão inválidas. Protocolos de comunicação entre
gerentes de cache são responsáveis por manter os dados consistentes e são conhecidos por
protocolos de coerência.
Chama-se de “princípio da localidade” à tendência de o processador ao longo de uma execução
referenciar instruções e dados da memória principal localizados em endereços próximos. Tal
tendência é justificada devido as estruturas de repetição e as estruturas de dados, vetores e tabelas
utilizarem a memória de forma subseqüente (um dado após o outro). Assim a aplicabilidade da
cache internamente ao processador fazendo o intermédio entre a memória principal e o
processador de forma a adiantar as informações da memória principal para o processador.
Um erro de MIS ocorre quando o processador necessita de um dado, e este não está presente no
cache, ele terá de realizar a busca diretamente na memória RAM, utilizando estados de espera
(wait states) e reduzindo o desempenho do computador. Como provavelmente será requisitado
novamente (localidade temporal) o dado que foi buscado na RAM é copiado na cache.
Níveis de Cache :
Cache L1 : uma pequena porção de memória estática presente dentro do processador. Em alguns
tipos de processador, como o Pentium 2, o L1 é dividido em dois níveis: dados e instruções (que
"dizem" o que fazer com os dados). A partir do Intel 486, começou a se colocar a L1 no próprio
processador. Geralmente tem entre 16KB e 512KB. O AMD Sempron 2600+ possui 64KB de
cache L1. Neste aspecto a Intel fica a perder em relação à AMD, visto possuir menor memória
cache nível 1 do que a sua concorrrente direta. Assim já existem processadores AMD com 128K
de memória cache nível 1, como por exemplo o AMD Turion 64 ML-40.
Cache L2 : possuindo o Cache L1 um tamanho reduzido e não apresentando uma solução ideal,
foi desenvolvido o cache L2, que contém muito mais memória que o cache L1. Ela é mais um
caminho para que a informação requisitada não tenha que ser procurada na lenta memória
principal. Alguns processadores colocam essa cache fora do processador, por questões
econômicas, pois uma cache grande implica num custo grande, mas há exceções, como no
Pentium II, por exemplo, cujas caches L1 e L2 estão no mesmo cartucho que está o processador.
É neste aspecto essencial que a Intel ganha todo o prestígio e rendimento dos seus processadores.
A memória cache L2 é, sobre tudo, um dos elementos essenciais para um bom rendimento do
processador mesmo que tenha um clock baixo. Um exemplo prático é o caso do Intel Xeon (para
servidores) que tem apenas 1.4 GHz de clock interno e ganha de longe do atual Intel Extreme,
pelo fato de possuir uma memória cache de 12Mb. Quanto mais alto é o clock do processador,
mais este aquece e mais instável se torna. Os processadores Intel Celeron tem tão fraco
desempenho por possuir menor memória cache L2. Um Pentium M 730 de 1.6 GHz de clock
interno, 533 MHz FSB e 2 MB de cache L2, tem rendimento semelhante a um Intel Pentium 4 2.4
GHz, aquece muito menos e torna-se muito mais estável e bem mais rentável do que o Intel
Celeron M 440 de 1.86 GHz de clock interno, 533 MHz FSB e 1 MB de cache L2.
Cache L3 : terceiro nível de cache de memória. Inicialmente utilizado pelo AMD K6-III (por
apresentar o cache L2 integrado ao seu núcleo) utilizava o cache externo presente na placa-mãe
91
como uma memória de cache adicional. Ainda é um tipo de cache raro devido a complexidade
dos processadores atuais, com suas áreas chegando a milhões de transístores por micrometros ou
picometros de área. Ela será muito útil, é possível a necessidade futura de níveis ainda mais
elevados de cache, como L4 e assim por diante.
Usando a técnica de nominada de Write-Back Cache a CPU escreve dados diretamente na cache,
cabendo ao sistema a escrita posterior da informação na memória principal. Como resultado o
CPU fica livre mais rapidamente para executar outras operações. Em contrapartida, a latência do
controlador pode induzir problemas de consistência de dados na memória principal, em sistemas
multiprocessados com memória compartilhada. Esses problemas são tratados por protocolos de
consistência da cache. Exemplo: A escrita de um endereço e feita inicialmente numa linha da
cache, e somente na cache. Quando mais tarde algum novo endereço necessitar desta linha da
cache, estando esta já ocupada, então o endereço inicial é guardado na memoria e o novo
endereço ocupa-lhe o lugar na respectiva linha da cache.
Para reduzir a frequência de escrita de blocos de endereços na memoria quando da substituição é
usado um "dirty bit", este é um bit de estado, ou seja, quando o endereço é instanciado
inicialmente numa linha da cache, estando essa linha vazia, o valor inicial é implicitamente '0',
quando o bloco do endereço e modificado (quando ocorre uma substituição) o valor inicial passa
a '1' e diz-se que o bloco do endereço está "dirty".
Vantagens: -A escrita ocorre à velocidade da cache; escritas múltiplas de um endereço requerem
apenas uma escrita na memória
Desvantagens: -Difícil de implementar; nem sempre existe consistência entre os dados existentes
na cache e na memoria; leituras de blocos de endereços na cache podem resultar em escritas de
blocos de endereços "dirty" na memoria.
92
Memórias não-voláteis: as memórias não-voláteis utilizam tecnologia semicondutora e são
elementos capazes de armazenar informações de forma definitiva. Memórias não-voláteis são
aquelas em que os dados não são perdidos quando a energia elétrica é suprimida. Exemplos de
memórias não-voláteis são as do tipo ROM(Read Only Memory), as do tipo PROM
(Programmable Read Only Memory) , as do tipo EPROM (Erasable Programmable Read Only
Memory), as do tipo EEPROM (ou EEROM) (Electricaly Erasable Programmable Read Only
Memory), as do tipo Flash dentre outros tipos.
Há outros tipos de memória não-voláteis que não utilizam tecnologia semicondutora, como por
exemplo os discos magnéticos, os discos óticos (DVDs e CDs), fitas magnéticas do tipo CCT
(Computer Compatible Tape), fitas do tipo DAT (Digital Audio Tape) , as antigas e populares
fitas do tipo cassette (k-7) e as fitas para vídeo cassettes padrão VHS.
Para gravar uma memória semicondutora dentre os tipos dados abaixo são necessários alguns
equipamentos específicos. Dentre as memórias tidas como sendo do tipo ROM destacam-se as
seguintes:
Sigla
Nome
Tecnologia
Read Only Memory (memória
ROM
Gravada na fábrica uma única vez
somente de leitura)
Programable Read Only
Memory (memória
PROM
Gravada pelo usuário uma única vez
programável somente de
leitura)
Pode ser gravada ou regravada por meio de um
equipamento que fornece as voltagens
Erasable Programable Read
adequadas em cada pino. Para apagar os dados
Only Memory (memória
EPROM
nela contidos, basta iluminar o chip com raios
programável e apagável
ultravioleta. Isto pode ser feito através de uma
somente de leitura)
pequena janela de cristal presente no circuito
integrado.
Electrically Erasable
Programable Read Only
Pode ser gravada, apagada ou regravada
Memory (memória
EEPROM
utilizando um equipamento que fornece as
programável e apagável
voltagens adequadas em cada pino.
eletronicamente somente de
leitura)
Uma memória do tipo ROM/PROM
Uma memória do tipo EPROM (observe a janela)
93
Conforme já mencionado, uma EPROM é programada por um dispositivo eletrônico que dá
voltagens maiores do que os usados normalmente em circuitos elétricos. Uma vez programado,
uma EPROM pode ser apagada apenas por exposição a uma forte luz ultravioleta. EPROMs são
facilmente reconhecíveis pela janela transparente no topo do pacote, pela qual o chip de silício
pode ser visto, e que admite luz ultravioleta durante o apagamento. Esta janela transparente é feita
de cristal para permitir a passagem da luz ultravioleta, pois o vidro comum bloqueia grande parte
do UV. O corpo de uma EPROM é feito em Cerâmica, pois o Epoxy comumente usado em outros
chips não seria apropriado para garantir a fixação da janela de cristal. O processo de apagamento
dura de 10 a 30 minutos.
Uma EPROM programada mantém seus dados por um período de aproximadamente 10 a 20 anos
e pode ser lida ilimitadas vezes. A janela de apagamento tem que ser mantida coberta para evitar
apagamento acidental pela luz do sol, rica em raios ultravioletas. Antigos chips de BIOS de PC
eram freqüentemente EPROMs, e a janela de apagamento era frequentemente coberta com um
adesivo contendo o nome do produtor da BIOS, a revisão da BIOS, e um aviso de Copyright.
Segue abaixo alguns modelos das antigas memórias EPROM , ainda encontradas em muitos
computadores e circuitos eletrônicos. Na fota acima, observem a janela por onde a luz ultravioleta
entrava para gerar a fotocorrente para apagar os dados armazenados. Uma vez gravadas com a
versão final, a janela era protegida com um fita colante escura, protegendo-a da luz solar.
Existem EPROMs de vários tamanhos físicos, formatos e capacidades. Veja a foto e tabela
abaixo:
Tipo de EPROM
Tamanho bits
Tamanho bytes
Tamanho
(hex)
Último endereço
(hex)
2716, 27C16
16 Kbit
2KBytes
800
007FF
2732, 27C32
32 Kbit
4KBytes
1000
00FFF
2764, 27C64
64 Kbit
8KBytes
2000
01FFF
27128, 27C128
128Kkbit
16KBytes
4000
03FFF
27256, 27C256
256 Kbit
32KBytes
8000
07FFF
27512, 27C512
512 Kbit
64KBytes
10000
0FFFF
27C010, 27C100
1Mbit
128KBytes
20000
1FFFF
27C020
2 Mbit
256 Kbytes
40000
3FFFF
27C040
4 Mbit
512 Kbyte
80000
7FFFF
NOTA: As séries de EPROMs 27x contendo um C no nome são baseados em CMOS, sem o C são
NMOS
94
Memórias voláteis: as memórias voláteis utilizam tecnologia semicondutora e são elementos
capazes de armazenar informações de forma temporária. Memórias voláteis são aquelas em que
os dados são perdidos quando a energia elétrica é suprimida. Exemplos de memórias voláteis são
as RAM(Random Access Memory) e suas assemelhadas (DRAM e SRAM). As memórias voláteis
se caracterizam pela velocidade com que respondem aos acessos da CPU.
Memória dinâmica (DRAM) : a memória dinâmica (Dinamic Random Access Memory) é a mais
barata das memórias RAM e, portanto, a mais utilizada nos computadores e são aquelas que
foram popularizadas como sendo as memórias RAM conhecidas. Na realidade, existem outras
memórias de acesso aleatório nos computadores, inclusive as não voláteis e portanto, é
importante ter o conhecimento de que o nome RAM é apenas uma popularização do nome da
memória principal dos computadores, utilizada para armazenar os programas e dados no
momento da execução.
O nome dinamica se refere à tecnologia utilizada para armazenar os dados e não à forma de
acessá-los. De modo simplista ela funciona como uma bateria que deve ser recarregada sempre
que apresentar carga insuficiente para alimentar o equipamento. A esse processo de “recarga” dáse o nome de refrescamento da memória (refresh), o que faz com esse tipo de memória seja mais
lenta e barata que as memórias do tipo SRAM.
Memória estática (SRAM) : a memória estática (Static Random Access Memory) não necessita
ser “refrescada” em intervalos regulares. Fabricada com circuitos eletrônicos conhecidos como
latches, elas guardam a informação pelo tempo em que estiverem alimentadas com eletricidade.
Devido à tecnologia empregue na sua construção, esse tipo de memória é mais cara e mais rápida
que as memórias do tipo DRAM.
Montador: dá-se o nome de montador (Assembler) ao programa que aceita como entrada um
arquivo fonte (arquivo texto) escrito em linguagem de montagem (linguagem Assembly) e gera
um arquivo escrito em linguagem de máquina, específico para uma particular CPU.
Placa-mãe : também denominada mainboard ou motherboard, é uma placa de circuito impresso,
que serve como base para a instalação dos demais componentes de um computador, como o
processador, memória RAM, os circuitos de apoio, as placas controladoras, os slots do
barramento e o chipset.
95
Plug and Play: essa tecnologia permite ao sistema operacional a deteccção e identificação de um
determinado dispositivo periférico recentemente acoplado ao computador. A adição desse novo
dispositivo é identificada e a localização do seu driver, dentre os vários drivers disponibilizados e
reconhecidos pelo sistema, é iniciada. Se o driver não for achado dentre esses vários drivers já
instalados, será solicitado a sua instalação e após o término exitoso desta, este novo dispositivoi
poderá ser utilizado, facilitando o gerenciamento do sistema.
Programa: dá-se o nome de programa à codificação de um determinado algoritmo em uma
determinada linguagem de programação.
Processo: dá-se o nome de processo a todo o programa sendo executado pela CPU. São
constituintes do processo os conteúdos de todos os registradores da CPU e todas as posições de
memória alocadas pelo processo e para o processo pelo sistema operacional.
96
Starvation (inanição) : em programação concorrente, a inanição ocorre quando um processo
nunca é executado, vindo a "morrer de fome", pois processos de prioridade maior sempre o
impedem de ser executado. Num ambiente computacional multitarefa, a execução de diversos
processos simultâneos deve seguir a uma regra de escalonamento destes para uso do processador.
Isto se deve ao fato de que, durante a mudança de contexto pelo processador, é feita a escolha do
próximo processo a ser executado a partir da prioridade deste. Quando o escalonamento não é
feito adequadamente, pode haver inanição. Uma solução para esta situação é a atribuição de um
tempo máximo de espera por algum evento.
A ocorrência da inanição se dá quando os programas rodam indefinidamente (razão pela qual
também se dá o nome de preterição indefinida a esta situação) e não fazem nenhum progresso em
seu processamento, ao contrário do deadlock, que ocorre quando os processos permanecem
bloqueados, dependendo da liberação dos recursos por eles alocados.
Num sistema dinâmico, as requisições de recursos ocorrem durante todo o tempo. Algumas
políticas são necessárias para subsidiar a decisão de quem vai ficar com qual recurso e em que
momento. Essas políticas, apesar de parecerem extremamente razoáveis, podem fazer com que
alguns processos nunca sejam servidos, apesar de não estarem em deadlock.
Um exemplo disso é a alocação de uma impressora. Considerando que o sistema utilize algum
algoritmo que garanta que a alocação da impressora não vai levar à situações de deadlock, e
considerando também que diversos processos desejam utilizá-la ao mesmo tempo. Deve-se
definir qual dos processos tem o direito de usá-la.
Um algorítmo possível para implementar a alocação da impressora é o que escolhe o processo
com o menor arquivo a ser impresso (assumindo que esta informação esteja disponível). Este
algoritmo maximiza o número de usuários satisfeitos com o sistema, e parece ser um algoritmo
justo. Consideremos, no entanto, o que acontece num sistema muito carregado, quando um
determinado processo tem um arquivo imenso a ser impresso. Cada vez que a impressora estiver
disponível, o sistema vai escolher, para usar a impressora, o processo com o menor arquivo a ser
impresso. Se houver um fluxo constante de processos no sistema com arquivos pequenos, aquele
ou aqueles com arquivos grandes jamais poderão usar a impressora. Eles apenas “morrerão de
fome” (como o próprio sentido da palavra inanição estabelece), ou seja, serão preteridos
indefinidamente em favor de outros, como se estivessem bloqueados.
A preterição por tempo indeterminado pode ser evitada usando-se uma política de alocação
baseada na regra do primeiro-a-chegar é o primeiro-a-ser-servido. Com esta abordagem, o
processo que espera há mais tempo é o primeiro a receber serviço por parte do recurso liberado.
Fica claro que qualquer dos processos será o mais antigo com o passar do tempo, recebendo,
assim, o direito ao uso do recurso pelo qual estiver esperando. Outra solução é fazer com que o
processo em inanição consiga aumentar a sua prioridade de acordo com o seu tempo de espera, o
que também pode resolver o problema.
Software: o termo software é atualmente utilizado para denotar todos os tipos de programas de
computadores, sejam eles de uso pessoal ou não. Exemplos de softwares são os editores de texto,
as planilhas eletrônicas, as linguagens de programação, sistemas operacionais etc.
97
Unicode: O Unicode é um padrão criado por um consórcio (www.unicode.org) para que sistemas
de todo o mundo consigam se comunicar. Define os caracteres utilizados em línguas do mundo
todo. Enquanto o padrão ASCII (American Standard Code for Information Interchange) utiliza 8
bits (com um universo possível de 256 caracteres diferentes), o padrão Unicode utiliza 16 bits
(aumentando o universo de caracteres para 65.536 - atualmente mais de 38.000 caracteres ja
foram mapeados neste padrão).
98
Download