Sei sulla pagina 1di 82

SUMRIO

1 INTRODUO E HISTRICO..........................................................................................................................4
1.1 HISTRICO..........................................................................................................................................................7
1.1.1 O Monitor Residente.................................................................................................................................9
1.1.2 Operao Off-Line..................................................................................................................................12
1.1.3 Buferizao.............................................................................................................................................14
1.1.4 Spooling..................................................................................................................................................15
1.1.5 Multiprogramao..................................................................................................................................15
1.1.6 Tempo Compartilhado.............................................................................................................................16
1.2 OS CONCEITOS DE INTERRUPO E TRAP..............................................................................................................19
2 PROCESSOS.......................................................................................................................................................22
2.1 O NCLEO DO SISTEMA OPERACIONAL.................................................................................................................27
2.1.1 Um Resumo das Funes do Ncleo.......................................................................................................28
2.2 ESCALONAMENTO DE PROCESSOS..........................................................................................................................28
2.2.1 Escalonamento FCFS ou FIFO..............................................................................................................30
2.2.2 Escalonamento Round Robin (RR)..........................................................................................................30
2.2.3 Escalonamento com Prioridades............................................................................................................32
2.2.4 Multilevel Feedback Queues...................................................................................................................33
2.2.5 Escalonamento com Prazos....................................................................................................................36
2.2.6 Escalonamento Shortest-Job-First (SJF)................................................................................................36
2.3 COMUNICAO ENTRE PROCESSOS (IPC).............................................................................................................38
2.3.1 Processamento Paralelo.........................................................................................................................38
2.3.1.1 Comandos PARBEGIN e PAREND (Dijkstra)......................................................................................................39
2.3.1.2 Comandos FORK e JOIN (Conway e Dennis)......................................................................................................40

2.3.2 Excluso Mtua......................................................................................................................................41


2.3.3 Regies Crticas......................................................................................................................................42
2.3.4 Primitivas de Excluso Mtua................................................................................................................43
2.3.5 Implementao de Primitivas de Excluso Mtua..................................................................................44
2.3.6 Excluso Mtua para N Processos.........................................................................................................45
2.3.7 Semforos...............................................................................................................................................45
2.3.7.1 Sincronizao de Processos com Semforos........................................................................................................
..47
2.3.7.2 A Relao Produtor-Consumidor............................................................................................................................
48
2.3.7.3 Semforos Contadores...........................................................................................................................................
.50
2.3.7.4 Implementando Semforos, P e V................................................................................................................
..........50

2.3.8 Monitores................................................................................................................................................51
2.3.9 Passagem de Mensagens.........................................................................................................................57
2.4 DEADLOCKS E ADIAMENTO INDEFINIDO.................................................................................................................57
2.4.1 Exemplos de Deadlocks..........................................................................................................................57
2.4.2 Um Deadlock de Trfego........................................................................................................................57
2.4.3 Um Deadlock Simples de Recursos.........................................................................................................58
2.4.4 Deadlock em Sistemas de Spooling.........................................................................................................58
2.4.5 Adiamento Indefinido .............................................................................................................................59
2.4.6 Conceitos de Recursos............................................................................................................................60
2.4.7 Quatro Condies Necessrias para Deadlock.......................................................................................61
2.4.8 Mtodos para Lidar com Deadlocks.......................................................................................................62
2.4.9 Preveno de Deadlocks.........................................................................................................................63
2.4.9.1 Negando a Condio Mutual Exclusion................................................................................................
.............63
2.4.9.2 Negando a Condio Hold and Wait...................................................................................................................
64
2.4.9.3 Negando a Condio No Preemption...............................................................................................
..................64
2.4.9.4 Negando a Condio Circular Wait.....................................................................................................
...............64

3 GERENCIAMENTO DE MEMRIA...............................................................................................................66
3.1 CONCEITOS BSICOS..........................................................................................................................................66
3.1.1 Ligao de Endereos (Address Binding)...............................................................................................67
3.1.2 Carregamento Dinmico (Dynamic Loading).........................................................................................69
3.1.3 Ligao Dinmica..................................................................................................................................70

3.1.4 Overlays..................................................................................................................................................71
3.2 ENDEREAMENTO LGICO E ENDEREAMENTO FSICO .............................................................................................72
3.3 SWAPPING.........................................................................................................................................................74
3.4 ALOCAO CONTGUA DE MEMRIA....................................................................................................................77
3.4.1 Alocao com Partio nica................................................................................................................78
3.5 MEMRIA VIRTUAL............................................................................................................................................82
3.5.1 Paginao...............................................................................................................................................82
3.5.2 Algoritmos de Paginao........................................................................................................................82
3.5.3 Segmentao...........................................................................................................................................82

PREFCIO
O texto existente nesta apostila no de minha autoria. Na verdade, trata-se de uma
sntese de vrios autores renomados na rea de sistemas operacionais, como Tannenbaum,
Deitel, Silberschatz, entre outros.
Entretanto, alguns exemplos e analogias foram adicionados aos textos originais para
facilitar a compreenso do assunto. Este material tambm no se prope a substituir a riqueza
presente nos livros publicados pelos autores mencionados, mas sim, servir como apoio s aulas
da disciplina de Sistemas Operacionais do Curso de Cincia da Computao desta
Universidade.
Dada a grande quantidade de trechos extrados praticamente na ntegra de alguns
livros, fica impraticvel referenciar todos eles. Em compensao, os livros citados na
bibliografia, ao final desta apostila, constituem as fontes principais do texto que a partir daqui
se inicia.
Espero que realmente este grande resumo possa ser til para que os alunos da
disciplina compreendam os aspectos mais importantes dos Sistemas Operacionais.

Prof. Celso Kopp Webber

1INTRODUO E HISTRICO
Podemos dizer sem receio que um computador sem software no passa de peso para
papel. Talvez a prova mais evidente nos dias atuais o sucesso nos sistemas operacionais da
Microsoft Corp. O grande motivo deste sucesso, apesar de muitas pessoas de renome afirmarem
que os sistemas operacionais da Microsoft no so tecnicamente bons, deve-se enorme
quantidade de software disponvel para estes sistemas operacionais.
Mas afinal, se importante para as pessoas a existncia de bons softwares que
ajudem nos seus trabalhos, como pode o sistema operacional influenciar na qualidade e na
disponibilidade de tais softwares?
Para responder esta pergunta, precisamos definir o que um sistema operacional.
Ele nada mais do que um programa de computador, que aps o processo de inicializao
(boot) da mquina, o primeiro a ser carregado, e que possui duas tarefas bsicas:

gerenciar os recursos de hardware de forma que sejam utilizados da melhor forma


possvel, ou seja, tirar o mximo proveito da mquina fazendo com que seus
componentes estejam a maior parte do tempo ocupados com tarefas existentes; e

prover funes bsicas para que programas de computador possam ser escritos com
maior facilidade, de modo que os programas no precisem conhecer detalhes da
mquina para poderem funcionar.

justamente neste segundo item que os sistemas operacionais podem ser bem
sucedidos ou no, em despertar interesse para que a indstria de software e os programadores
independentes construam programas para determinados sistemas operacionais. Isto justifica
parte do sucesso do Microsoft Windows, pois, ao mesmo tempo que ele prov uma interface
bastante amigvel com o usurio, para o programador, no to difcil criar um programa com
janelas, botes, listas, etc, como seria num sistema operacional como o MS-DOS. Alm disso,
os sistemas operacionais da Microsoft rodam no hardware mais popular hoje em dia: os
computadores baseados em IBM PC.
Computadores modernos possuem um ou mais processadores, memria principal,
dispositivos de entrada e sada como discos, fitas, teclado, mouse, monitor, interface de rede,
entre outros. Escrever programas que utilizem um computador com esta complexidade de forma

eficiente muito difcil e trabalhoso. exatamente neste ponto que entram as funes do
sistema operacional: abstrair as particularidades do hardware dos programas, fornecendo a eles
facilidades para sua operao, tais como: rotinas de acesso a dispositivos diversos; funes de
armazenamento de dados como criao de arquivos, leitura e escrita de dados; e rotinas de
acesso aos dispositivos de interao com a mquina, como teclado, mouse, monitor, etc.
Dada a existncia de softwares como o sistema operacional, os programas
normalmente so classificados como software bsico (que inclui o sistema operacional), e
softwares de aplicao, que so voltados a resolver problemas dos usurios.
Podemos visualizar atravs de um diagrama a integrao entre hardware, software
bsico, e softwares aplicativos, como mostra a figura 1.1.
Figura 1.1 Integrao entre hardware, software bsico e software aplicativo

Sistema Bancrio

Controle de
Estoques

Jogos

Compiladores

Editores

Interpretador de
comandos (shell)

Sistema Operacional

Programas de
Aplicao

Programas de Sistema
(software bsico)

Linguagem de Mquina
Microprogramao
Dispositivos Fsicos

Hardware

Olhando para o diagrama, veremos que o que chamamos de hardware na


verdade composto de trs camadas. Nem todas as mquinas seguem este esquema, algumas
podem ter uma camada a menos, ou mesmo camadas adicionais, mas basicamente, os
computadores seguem o esquema ilustrado na figura 1.1.
No nvel mais inferior, temos os dispositivos eletrnicos em si, como o processador,
os chips de memria, controladores de disco, teclado, e outros dispositivos, barramentos, e
qualquer dispositivo adicional necessrio para o funcionamento do computador. Um nvel
acima, temos a camada de microprogramao, que de forma geral, so pequenos passos
(chamados de microoperaes) que formam uma instruo de processador completa, como
ADD, MOV, JMP, etc.
O conjunto de instrues do computador chamado de linguagem de mquina, e
apesar de ser uma espcie de linguagem, podemos dizer que faz parte do hardware porque os
fabricantes a incluem na especificao do processador, para que os programas possam ser
escritos. Afinal, de nada adianta uma mquina maravilhosa, se no existir documentao
alguma de como ela funciona. Assim, as instrues que a mquina entende so consideradas
parte integrante do hardware.
As instrues tambm incluem, geralmente, operaes que permitem ao
processador comunicar-se com o mundo externo, como controladores de disco, memria,
teclado, etc. Como a complexidade para acesso a dispositivos muito grande, tarefa do
Sistema Operacional esconder estes detalhes dos programas. Assim, o sistema operacional
pode, por exemplo, oferecer aos programas uma funo do tipo LEIA UM BLOCO DE UM
ARQUIVO, e os detalhes de como fazer isso ficam a cargo do sistema operacional.
Acima do sistema operacional esto os demais programas utilizados pelo usurio
final, mas alguns deles ainda so considerados software bsico, como o sistema operacional.
Entre eles podemos citar o shell, que consiste do interpretador de comandos do usurio, ou seja,
a interface com o usurio. Nos sistemas operacionais mais recentes, freqentemente o shell
uma interface grfica (ou em ingls GUI Graphics User Interface). Raramente, numa
interface grfica bem elaborada, o usurio precisa digitar comandos para o computador. A
maneira mais comuns de executar programas, copiar e mover arquivos, entre outras atividades
mais comuns, atravs do uso do mouse. Nos tempos do MS-DOS, o teclado era o dispositivo
de entrada dominante, por onde o usurio entrava todos os comandos para realizar suas tarefas
do dia a dia.
O que muito importante observar quanto ao software bsico que, apesar de que
editores (ex: bloco de notas do Windows), compiladores (ex: compilador C no Unix), e

interpretadores de comando (ex: command.com ou explorer.exe no Windows) normalmente


serem instalados junto como sistema operacional em um computador, eles no so o sistema
operacional. Eles apenas utilizam o sistema operacional. Portanto, o shell que normalmente
usamos em um sistema operacional nada mais do que um programa que utiliza servios do
sistema operacional, mas com a finalidade de permitir que os usurios realizem suas tarefas
mais freqentes: executar programas e trabalhar com arquivos.
A grande diferena entre o sistema operacional, e os programas que rodam sobre
ele, sejam software bsico ou software aplicativo, que o sistema operacional roda em modo
kernel (ou supervisor), enquanto os demais programas rodam em modo usurio. Estes dois
modos de operao dos processadores dos computadores diferem no fato de que em modo
supervisor, um programa tem acesso a todo o hardware, enquanto que os programas que rodam
em modo usurio, tem acesso somente a determinadas regies de memria, no podem acessar
dispositivos diretamente, e precisam pedir para o sistema operacional quando necessitam de
alguma tarefa especial. Isto garante que os programas dos usurios, no acabem por invadir
reas de memria do sistema operacional, e acabem por travar o sistema. Isto tambm
possibilita que programas de diferentes usurios estejam rodando na mesma mquina, de forma
que um usurio no consiga interferir nos programas de outro.

1.1Histrico
Inicialmente, existiu somente o hardware do computador. Os primeiros
computadores eram mquinas fisicamente muito grandes que funcionavam a partir de um
console, que consiste em um perifrico ou terminal que pode ser usado para controlar a mquina
por mtodos manuais, corrigir erros, determinar o estado dos circuitos internos e dos
registradores e contadores, e examinar o contedo da memria. O console o meio de
comunicao entre o homem e a mquina, ou seja, o meio por onde o operador fornece as
entradas e por onde recebe as sadas. O console das primeiras mquinas consistia em chaves
pelas quais o operador inseria informaes, e por luzes indicativas das sadas, que podiam ser
impressas ou perfuradas em uma fita de papel.
Com o passar do tempo, o uso de teclados para entrada de dados se tornou comum,
e a sada passou a ser inicialmente impressa em papel. Posteriormente o console assumiu a
forma de um terminal com teclado e vdeo.
Nesta poca, os programadores que quisessem executar um programa, deveriam
carreg-lo para a memria manualmente atravs de chaves no painel de controle, ou atravs de

fita de papel ou cartes perfurados. Em seguida, botes especiais eram apertados para iniciar a
execuo do programa. Enquanto o programa rodava, o programador/operador podia monitorar
a sua execuo pelas luzes do console. Se erros eram descobertos, o programa precisava ser
interrompido, e o programador podia examinar os contedos da memria e registradores,
depurando-o diretamente do console. A sada era impressa diretamente, ou ainda perfurada em
fita ou carto para impresso posterior.
As dificuldades nesta poca eram evidentes. O programador era tambm o operador
do sistema de computao. Devido escassez de recursos, a maioria dos sistemas usava um
esquema de reserva para alocao de tempo da mquina. Se voc quisesse usar o computador,
deveria reservar um horrio em uma planilha.
Alm disso, este mtodo no era eficiente na utilizao de recursos. Supondo que
voc tivesse reservado 1 hora de tempo de computador para executar um programa em
desenvolvimento. Se voc tivesse alguns erros desagradveis voc provavelmente no
terminaria dentro de 1 hora, e deveria juntar seus resultados e liberar a mquina para a prxima
pessoa da fila. Por outro lado, se o seu programa rodasse sem problemas, voc poderia terminar
tudo em 35 minutos, e a mquina ficaria ociosa at a prxima reserva de horrio.
Como as mquinas nesta poca custavam muito dinheiro, pensou-se em algumas
solues para agilizar a tarefa de programao. Leitoras de cartes, impressoras de linha e fitas
magnticas tornaram-se equipamentos comuns. Montadores (assemblers), carregadores
(loaders) e ligadores (linkers) foram projetados. Bibliotecas de funes comuns foram criadas
para serem copiadas dentro de um novo programa sem a necessidade de serem reescritas.
Um bom exemplo do uso das bibliotecas de funes sobre as rotinas que
executavam operaes de entrada e sada (E/S). Cada novo dispositivo tinha suas prprias
caractersticas, necessitando de cuidadosa programao. Uma subrotina especial foi escrita para
cada tipo de dispositivo de E/S. Essas subrotinas so chamadas de device drivers (controladores
de dispositivos), e sabem como conversar com o dispositivo para o qual foram escritas. Uma
tarefa simples como ler um caractere de um disco pode envolver seqncias complexas de
operaes especficas do dispositivo. Ao invs de escrever cdigo a cada momento o device
driver simplesmente utilizado a partir de uma biblioteca.
Mais tarde, compiladores para linguagens de alto nvel, como FORTRAN e
COBOL, surgiram, facilitando muito a tarefa de programao, que antes era feita diretamente
na linguagem da mquina. Entretanto a operao do computador para executar um programa em
uma linguagem de alto nvel era bem mais complexa.
Por exemplo, para executar um programa FORTRAN, o programador deveria

primeiramente carregar o compilador FORTRAN para a memria. O compilador normalmente


era armazenado em fita magntica, e portanto a fita correta deveria ser carregada para a unidade
leitora de fitas magnticas. Uma vez que o compilador estivesse pronto, o programa fonte em
FORTRAN era lido atravs de uma leitora de cartes e escrito em outra fita. O compilador
FORTRAN produzia sada em linguagem assembly que precisava ser montada (assembled), isto
, convertida para cdigo de mquina. A sada do montador era ligada (linked) para suportar
rotinas de biblioteca. Finalmente, o cdigo objeto do programa estaria pronto para executar e
seria carregado na memria e depurado diretamente no console, como anteriormente.
Podemos perceber que poderia existir um tempo significativo apenas para a
preparao da execuo de um job (tarefa). Vrios passos deveriam ser seguidos, e em caso de
erro em qualquer um deles, o processo deveria ser reiniciado aps a soluo do problema.

1.1.1O Monitor Residente


O tempo de preparao de um job era um problema real. Durante o tempo em que
fitas eram montadas ou o programador estava operando o console, a UCP (Unidade Central de
Processamento) ficava ociosa. Vale lembrar que no passado muitos poucos computadores
estavam disponveis e eram muito caros (milhes de dlares). Alm disso, os custos
operacionais com energia, refrigerao, programadores, etc., tornava ainda mais cara sua
manuteno. Por isso, tempo de processamento tinha muito valor, e os proprietrios dos
computadores os queriam ocupados o mximo do tempo possvel. O computador precisava ter
um alta utilizao para que o investimento fosse compensado.
Uma primeira soluo foi contratar um profissional que operasse o computador. O
programador no precisava mais operar a mquina, e assim que um job terminasse, o operador
podia iniciar o prximo; no existia a ociosidade de tempo devido reserva de tempo de
computador no utilizada. J que o operador tinha mais experincia com a montagem de fitas, o
tempo de preparao foi reduzido. O usurio apenas fornecia cartes ou fitas perfuradas
contendo o programa, e instrues necessrias para sua execuo. Caso erros ocorressem
durante a execuo do programa, o operador emitia uma listagem dos contedos da memria e
registradores para que o programador pudesse depurar seu programa. Em seguida o prximo
job era posto em execuo, e assim por diante.
Alm disso, para reduzir ainda mais o tempo de preparao, jobs com necessidades
similares eram agrupados (batched) e executados em grupo pelo computador. Por exemplo,
supondo que o operador tivesse recebido um job FORTRAN, um COBOL, e outro FORTRAN.

Se ele os executasse nessa ordem, ele teria que preparar o job FORTRAN (carregar fitas de
compilador, etc.), ento o COBOL, e novamente o FORTRAN. Se ele executasse os dois jobs
FORTRAN como um grupo ele prepararia o ambiente FORTRAN apenas uma vez
economizando tempo de preparao.
Esta abordagem marcou uma poca, onde o processamento em batch (lotes)
definiu uma forma de utilizao do computador: os usurios preparavam seus programas e
dados, entregavam-nos ao operador do computador, que os agrupava segundo suas necessidades
e os executava, produzindo as sadas para serem devolvidas aos respectivos programadores.
Mesmo assim, quando um job parava, o operador teria que notar o fato observando
no console, determinar porque o programa parou (trmino normal ou anormal), listar contedos
de memria se necessrio e ento carregar a leitora de cartes ou de fita de papel com o
prximo job e inicializar o computador novamente. Durante a transio entre os jobs,
novamente a UCP ficava ociosa.
Para resolver este problema, foi desenvolvido um seqenciador automtico de jobs,
que consistia em um primeiro sistema operacional rudimentar. Sua funo era controlar a
transferncia automtica de um job para outro. Este programa foi implementado sob a forma de
um monitor residente, sempre presente na memria da mquina para este fim.
Assim que o computador era ligado, o monitor residente era chamado, e transferia o
controle para um programa. Quando o programa terminava, ele retornava o controle para o
monitor residente, que ia para o prximo programa. Assim, o monitor residente fornecia uma
seqncia automtica entre programas e jobs.
Para que o monitor residente pudesse saber qual programa deveria ser executado e
de que forma, cartes de controle foram introduzidos, de maneira muito semelhante s
instrues que os operadores recebiam dos programadores para execuo de seus programas.
Assim, alm do programas e dos dados para um job, cartes especiais de controle eram
introduzidos entre os cartes de programa e dados do job a executar, como por exemplo:
$JOB - Primeiro carto, indicando o incio de um job;
$FTN - Executar o compilador FORTRAN;
$LOAD - Carregar o programa compilado;
$RUN - Executar o programa carregado;
$END - Fim do job.
Os cartes de incio e fim de job eram geralmente utilizados para contabilizar o

tempo de uso da mquina, para que seu tempo de processamento pudesse ser cobrado do
usurio. Por isso, s vezes incluam parmetros indicando o usurio do job, nome do job, etc.
Para distinguir cartes de controle dos demais cartes era necessrio identific-los
com um caractere ou um padro especial no carto. Em nosso exemplo, o smbolo do dlar ($)
foi utilizado para este fim. A linguagem JCL (Job Control Language) da IBM usava duas barras
(//) nas primeiras duas colunas. A figura 1.1 ilustra este cenrio.

$END
dados do programa

$RUN
$LOAD
pgm. a ser compilado

$FTN
$JOB

Figura 1.1 - Deck de cartes de um job


Um monitor residente tem vrias partes identificveis. Uma delas o interpretador
de cartes de controle, responsvel pela leitura e extrao das instrues dos cartes no instante
da execuo. O interpretador de cartes de controle chama um carregador em intervalos para
carregar programas do sistema e programas de aplicao para a memria. Dessa forma, um
carregador (loader) uma parte do monitor residente. Ambos o interpretador de cartes de
controle e o carregador precisam executar (E/S), assim o monitor residente tem um grupo de
drivers de dispositivo para os dispositivos de do sistema. Freqentemente, os programas de
aplicao e do sistema esto ligados (linked) aos mesmos drivers de dispositivo, fornecendo
continuidade na sua operao, bem como armazenando espao de memria e tempo de
programao. Um esquema de um monitor residente mostrado na figura 1.2

Monitor
Residente

Carregador
Seqenciador automtico de jobs
Interpretador dos cartes de controle
rea do programa do usurio

Figura 1.2 - Modelo de memria de um monitor residente

Sistemas batch utilizando este mtodo funcionavam razoavelmente bem. O monitor


residente fornece seqenciamento automtico dos jobs conforme a indicao dos cartes de
controle. Quando um carto de controle indica a execuo de um programa, o monitor carrega o
programa para a memria e transfere o controle para o mesmo. Quando o programa termina, ele
retorna o controle para o monitor, que l o prximo carto de controle, carrega o programa
apropriado e assim por diante. Este ciclo repetido at que todos os cartes de controle sejam
interpretados para o job. Ento o monitor continua automaticamente com o prximo job.

1.1.2Operao Off-Line
O uso de sistemas batch com seqenciamento automtico de jobs aumentou a
performance do sistema. Entretanto, ainda assim a UCP ficava freqentemente ociosa, devido
baixssima velocidade dos dispositivos mecnicos em relao aos eletrnicos.
Os dispositivos de E/S mais lentos podem significar que a UCP fica freqentemente
esperando por E/S. Como um exemplo, um montador ou compilador pode ser capaz de
processar 300 ou mais cartes por segundo. Uma leitora de cartes mais rpida, por outro lado,
pode ser capaz de ler apenas 1200 cartes por minuto (20 cartes por segundo). Isto significa
que montar um programa com 1200 cartes precisa de apenas 4 segundos de UCP, mas 60
segundos para ser lido. Dessa forma, a UCP fica ociosa por 56 dos 60 segundos, ou 93.3% do
tempo. A utilizao de UCP resultante de apenas 6.7%. O processo similar para operaes de
sada. O problema que, enquanto uma operao de E/S est acontecendo, a UCP est ociosa,
esperando que o E/S termine; enquanto a UCP est executando, os dispositivos de E/S esto
ociosos.
Uma soluo simples era substituir as lentas leitoras de carto (dispositivos de
entrada) e impressoras de linha (dispositivos de sada) por unidades de fita magntica. A
maioria dos sistemas no final dos anos 50 e comeo dos anos 60 eram sistemas batch cujos jobs
eram lidos de leitoras de carto e escritos em impressoras de linha ou perfuradoras de cartes.
Ao invs de a UCP ler diretamente os cartes, os cartes eram primeiro copiados para uma fita
magntica. Quando a fita estava suficientemente cheia ela era transportada para o computador.
Duas abordagens para esta soluo (operao off-line) foram usadas. Dispositivos
especficos (leitoras de carto, impressoras de linha) foram desenvolvidos para provocar sada
ou entrada direta de fitas magnticas. A outra abordagem foi dedicar um pequeno computador
para a tarefa de copiar de e para a fita. O pequeno computador foi um satlite do computador

principal. Processamento satlite foi um dos primeiros casos de mltiplos sistemas de


computao trabalhando em conjunto para aumentar a performance.
A principal vantagem da operao off-line foi de que o computador principal no
estava mais restrito pela velocidade das leitoras de carto e impressoras de linha, e sim pela
velocidade das unidades de fita magntica mais rpidas. Essa tcnica de usar fitas magnticas
para todo o E/S podia ser aplicada com qualquer unidade de equipamento de registro (leitoras e
perfuradoras de carto, leitoras e perfuradoras de fitas de papel, impressoras).
Alm disso, nenhuma modificao precisa ser feita para adaptar programas de
aplicao da operao direta para off-line. Considere um programa que executa em um sistema
com uma leitora de cartes acoplada. Quando ele quer um carto, ele chama o driver de
dispositivo da leitora de carto no monitor residente. Se a operao de carto est em modo offline, apenas o driver de dispositivo deve ser modificado. Quando um programa precisa de um
carto de entrada, ele chama a mesma rotina de sistema como antes. Entretanto, agora o cdigo
para aquela rotina no o driver da leitora de cartes, mas uma chamada para o driver da fita
magntica. O programa de aplicao recebe a mesma imagem do carto em ambos os casos.
Essa habilidade de executar um programa com dispositivos de E/S diferentes
chamada independncia de dispositivo. Independncia de dispositivo torna-se possvel pela
existncia de um sistema operacional que determina qual o dispositivo que um programa
realmente usa quando faz o pedido de E/S. Programas so escritos para usar dispositivos de E/S
lgicos. Cartes de controle (ou outros comandos) indicam como os dispositivos lgicos
deveriam ser mapeados em dispositivos fsicos.
O ganho real da operao off-line vem da possibilidade de usar mltiplos sistemas
leitora-para-fita e fita-para-impressora para uma mesma UCP. Se a UCP pode processar com o
dobro da velocidade da leitora, ento duas leitoras trabalhando simultaneamente podem
produzir fita suficiente para manter a UCP ocupada. Por outro lado, agora h um atraso mais
longo para conseguir executar um job em particular. Ele deve ser lido antes para a fita. Existe o
atraso at que jobs suficientes sejam lidos para a fita para preench-la. A fita deve ser ento
rebobinada, descarregada, manualmente carregada para a UCP e montada em um drive de fita
livre. Alm disso, jobs similares podem ser agrupados em uma fita antes de serem levados para
o computador, fazendo com que s vezes um job tenha que esperar seu agrupamento com
outros jobs similares em uma fita at que possa ser levado para a UCP.

1.1.3Buferizao
Processamento off-line permite a sobreposio de operaes de UCP e E/S pela
execuo dessas duas aes em duas mquinas independentes. Se desejamos atingir tal
sobreposio em uma nica mquina, comandos devem ser colocados entre os dispositivos e a
UCP para permitir uma separao similar de execuo. Tambm, uma arquitetura adequada
deve ser desenvolvida para permitir buferizao.
Buferizao o mtodo de sobrepor E/S de um job com sua prpria computao. A
idia muito simples. Depois de os dados terem sido lidos e a UCP estar pronta para iniciar a
operao nos mesmos, o dispositivo de entrada instrudo para iniciar a prxima entrada
imediatamente. Dessa forma, a UCP e o dispositivo de entrada de dados ficam ambos ocupados.
Com sorte, no instante em que a UCP est pronta para o prximo item de dado (registro), o
dispositivo de entrada ter terminado de l-lo. A UCP pode ento comear o processamento dos
novos dados lidos, enquanto o dispositivo de entrada comea a ler os dados seguintes. De forma
semelhante isto pode ser feito para a sada. Nesse caso, a UCP cria dados que so colocados em
um buffer at que o dispositivo de sada possa receb-lo.
Na prtica, raro UCP e dispositivos de E/S estarem ocupados o tempo todo, j que
ou a UCP ou o dispositivo de E/S termina primeiro. Se a UCP termina primeiro, ela deve
esperar at que o prximo registro seja lido para a memria. importante observar que a UCP
no fica o tempo todo ociosa, no mximo o tempo que ficaria se no estivesse sendo utilizada
buferizao.
Por outro lado, se o dispositivo de entrada de dados termina primeiro, ele pode tanto
esperar como continuar com a leitura do prximo registro. Neste caso ele s dever parar
quando os buffers estiverem cheios. Para que o dispositivo de entrada continue sempre
trabalhando, normalmente os buffers costumam ter tamanho suficiente para mant-lo sempre
ocupado.
A buferizao geralmente uma funo do sistema operacional. O monitor
residente ou os drivers de dispositivo incluem buffers do sistema de E/S para cada dispositivo
de E/S. Assim, chamadas ao driver de dispositivo pelos programas de aplicao normalmente
causam apenas uma transferncia do buffer para o sistema.
Apesar da buferizao ser de alguma ajuda, ela raramente suficiente para manter a
UCP sempre ocupada, j que os dispositivos de E/S costumam ser muito lentos em relao
UCP.

1.1.4Spooling
Com o passar do tempo, dispositivos baseados em discos tornaram-se comuns e
facilitaram muito a operao off-line dos sistemas. A vantagem que em um disco era possvel
escrever e ler a qualquer momento, enquanto que uma fita precisava ser escrita at o fim para
ento ser rebobinada e lida.
Em um sistema de disco, cartes so diretamente lidos da leitora de cartes para o
disco. Quando um job executado, o sistema operacional satisfaz seus pedidos por entrada da
leitora de cartes pela leitura do disco. Da mesma forma, quando um job pede a impresso de
uma linha para a impressora, esta copiada em um buffer do sistema que escrito para o disco.
Quando a impressora fica disponvel, a sada realmente impressa.
Esta forma de processamento chamada de spooling (spool = Simultaneous
Peripheral Operation On-Line). Spooling utiliza um disco como um buffer muito grande para
ler tanto quanto possa dos dispositivos de entrada e para armazenar arquivos de sada at que os
dispositivos de sada estejam aptos para receb-los. Esta tcnica tambm muito utilizada para
comunicao com dispositivos remotos. A UCP envia os dados atravs dos canais de
comunicao para uma impressora remota (ou aceita um job completo de entrada de uma leitora
de cartes remota). O processamento remoto feito em sua prpria velocidade sem a
interveno da UCP. A UCP apenas precisa ser notificada quando o processamento termina,
para que possa passar para o prximo conjunto de dados do spool.
A diferena entre buferizao e spooling que enquanto a buferizao sobrepe o
processamento de um job com seu prprio E/S, o spooling sobrepe o E/S de um job com o
processamento de outros jobs. Assim, a tcnica spooling mais vantajosa do que a buferizao.
O nico efeito colateral a necessidade de algum espao em disco para o spool, alm de
algumas tabelas em memria.
Outra vantagem do spooling vem do fato de que a tcnica fornece uma estrutura de
dados muito importante, que a lista de jobs. A performance pode ser aumentada, pois os vrios
jobs armazenados no disco podem ser processados em qualquer ordem que o sistema
operacional decidir, buscando o aumento de utilizao da UCP (escalonamento de jobs).
Quando jobs so lidos diretamente de cartes ou fita magntica, no possvel executar os jobs
fora de ordem.

1.1.5Multiprogramao
O aspecto mais importante do escalonamento de jobs a habilidade de

multiprogramao. As tcnicas de operao off-line, buferizao e spooling tm suas


limitaes na sobreposio de E/S. Em geral, um nico usurio no pode manter tanto UCP e
dispositivos de E/S ocupados o tempo todo. A multiprogramao aumenta a utilizao de UCP,
pois organiza os vrios jobs de forma que a UCP sempre tenha algo para processar.
A multiprogramao funciona da seguinte maneira: inicialmente o sistema
operacional escolhe um dos jobs da lista de jobs e comea a execut-lo. Eventualmente, o job
deve esperar por alguma tarefa, como a montagem de uma fita, um comando digitado pelo
teclado, ou mesmo o trmino de uma operao de E/S. Em um sistema monoprogramado a
UCP permaneceria ociosa. Por outro lado, em um sistema multiprogramado, o sistema
operacional simplesmente troca e executa outro job. Quando este novo job precisa esperar, a
UCP troca para outro job e assim por diante. Em um dado momento, o primeiro job no precisa
mais esperar e ganha a UCP. Assim, sempre que existirem jobs a serem processados, a UCP no
ficar ociosa.
Sistemas operacionais multiprogramados so bastante sofisticados. Para que vrios
jobs estejam prontos para executar, necessrio que todos estejam presentes na memria RAM
da mquina simultaneamente. Isto acarreta em um gerenciamento de memria para os vrios
jobs. Alm disso, se vrios jobs esto prontos para executar ao mesmo tempo, o sistema deve
escolher qual deles deve ser executado primeiro. A poltica de deciso de qual job ser
executado chamada de escalonamento de UCP. Por fim, o sistema operacional deve garantir
que vrios jobs rodando concorrentemente no afetem uns aos outros em todas as fases do
sistema operacional, incluindo escalonamento de processos, armazenamento de disco e
gerenciamento de memria.

1.1.6Tempo Compartilhado
O conceito de sistemas de tempo compartilhado, tambm chamados de
multitarefa, uma extenso lgica de multiprogramao. Neste ambiente, mltiplos jobs so
executados simultaneamente, sendo que a UCP atende cada job por um pequeno tempo, um a
um em seqncia. Os tempos dedicados para cada job so pequenos o suficiente para que os
usurios consigam interagir com cada programa sem que percebam que existem outros
programas rodando. Quando muitos programas esto sendo executados, a impresso que o
usurio tem de que o computador est lento, pois a UCP tem mais jobs para atender, e
portanto aumenta o tempo entre os sucessivos atendimentos para um determinado job.
fcil de entender como funcionam sistemas de tempo compartilhado quando

comparados com sistemas batch. Neste tipo de sistema operacional, um fluxo de jobs separados
lido (de uma leitora de cartes, por exemplo), incluindo seus cartes de controle que
predefinem o que faz o job. Quando o job termina, seu resultado normalmente impresso, e o
prximo job posto em execuo.
A principal caracterstica (e desvantagem) deste sistema a falta de interao entre
o usurio e o programa em execuo no job. O usurio precisa entregar ao operador o programa
que ele deseja executar, incluindo seus dados de entrada. Algum tempo depois (podendo
demorar minutos, horas ou mesmo dias), a sada do job retornada. Este tempo entre a
submisso do job e seu trmino, chamado de tempo de turnaround, vai depender da quantidade
de processamento necessria, tempo de preparao necessrio, e da quantidade de jobs que
estavam na fila antes dele ser submetido ao processamento.
Existem algumas dificuldades com o sistema batch do ponto de vista do
programador ou do usurio. J que o usurio no pode interagir com o job que est executando,
o usurio deve indicar os cartes de controle para manipularem todos os resultados possveis.
Em um job de mltiplos passos, passos subseqentes podem depender do resultado dos
anteriores. A execuo de um programa, por exemplo, pode depender do sucesso da
compilao. Pode ser difcil definir completamente o que fazer em todos os casos.
Outra dificuldade em um sistema batch que programas devem ser depurados
estaticamente, a partir de uma listagem. Um programador no pode modificar um programa
quando ele est sendo executado para estudar o seu comportamento, como hoje possvel na
maioria dos ambientes de programao.
Um sistema de computao interativo (chamado de hands-on), fornece
comunicao on-line entre o usurio e o sistema. O usurio d instrues ao sistema operacional
ou para um programa diretamente, e recebe uma resposta imediata. Usualmente, um teclado
usado para a entrada de dados e uma impressora ou monitor de vdeo para a sada de dados.
Este tipo de terminal s apareceu algum tempo depois, com o barateamento de componentes
eletrnicos neles utilizados. Quanto o sistema operacional termina a execuo de um comando,
ele passa a aceitar outros comandos do teclado do usurio, e no mais de uma leitora de cartes.
Assim o usurio fornece o comando, espera pela resposta e decide o prximo comandos,
baseado no resultado do comando anterior. O usurio pode fazer experimentos com facilidade e
pode ver resultados imediatamente.
Sistemas batch so bastante apropriados para executar jobs grandes que precisam
de pouca interao. O usurio pode submeter jobs e retornar mais tarde para buscar os
resultados; no necessrio esperar seu processamento. Por outro lado, jobs interativos

costumam ser compostos por vrias aes pequenas, onde os resultados de cada ao podem ser
imprevisveis. O usurio submete o comando e espera pelos resultados. O tempo de resposta
deve ser pequeno da ordem de segundos no mximo. Um sistema interativo usado quando
necessrio um tempo de resposta pequeno.
Conforme j vimos, no incio dos tempos da computao, apesar de primitivos, os
sistemas eram interativos. Um novo processamento s comeava aps o operador analisar os
resultados do job anterior e decidir que ao tomar. Para aumentar o uso de UCP, sistemas
batch foram introduzidos, o que realmente fez com que os computadores ficassem menos tempo
ociosos. Entretanto, no havia interatividade nenhuma do usurio ou programador com o
sistema.
Sistemas de tempo compartilhado foram desenvolvidos para fornecer o uso
interativo de um sistema de computao a custos razoveis. Um sistema operacional de tempo
compartilhado (time-sharing) usa escalonamento de UCP e multiprogramao para fornecer
a cada usurio uma pequena poro de tempo de computador.
Um sistema operacional de tempo compartilhado permite que muitos usurios
compartilhem o computador simultaneamente. J que cada ao ou comando em um sistema
de tempo compartilhado tende a ser pequena, apenas uma pequena quantidade de tempo de UCP
necessria para cada usurio. Conforme o sistema troca de um usurio para outro, cada
usurio tem a impresso de ter seu prprio computador, enquanto na realidade um computador
est sendo compartilhado entre muitos usurios.
A idia de tempo compartilhado foi demonstrada no incio de 1960, mas j que
sistemas de tempo compartilhado so mais difceis e custosos para construir (devido aos
numerosos dispositivos de E/S necessrios), eles somente tornaram-se comuns at o incio dos
anos 70. Conforme a popularidade destes sistemas cresceu, pesquisadores tentaram combinar os
recursos de sistemas batch e de tempo compartilhado em um nico sistema operacional. Muitos
sistemas que foram inicialmente projetados como sistemas batch foram modificados para criar
um subsistema de tempo compartilhado. Por exemplo, o sistema batch OS/360 da IBM foi
modificado para suportar a opo de tempo compartilhado (Time Sharing Option - TSO). Ao
mesmo tempo, maioria dos sistemas de tempo compartilhado foi adicionado um subsistema
batch. Hoje em dia, a maioria dos sistemas fornecem ambos processamento batch e de tempo
compartilhado, embora seu projeto bsico e uso sejam de um ou de outro tipo.
Sistemas operacionais de tempo compartilhado so sofisticados. Eles fornecem um
mecanismo para execuo concorrente. Como na multiprogramao, vrios jobs deve ser
mantidos simultaneamente na memria, o que requer alguma forma de gerenciamento de

memria, proteo e escalonamento de UCP. Como a memria tem tamanho limitado, e em


dadas situaes alguns jobs tero que ser retirados da memria e gravados temporariamente em
disco, para que outros programas possam ser lidos do disco e postos em execuo na memria.
Quando aquele job novamente precisar de continuao em sua execuo, ele ser trazido de
volta para a memria.
Os primeiros sistemas operacionais para microcomputadores eram muito simples,
pois o poder computacional dos primeiros micros era suficiente para atender somente a
programas de um nico usurio. Alm do mais, os microcomputadores foram projetados na
poca para serem utilizados no mximo por uma pessoa em um determinado momento. Com o
passar dos anos, os microcomputadores ganharam poder de processamento equivalente a
computadores que ocupavam salas inteiras no passado. Para aproveitar este potencial, os
microcomputadores ganharam sistemas operacionais multitarefa, permitindo ao usurio
executar mais de uma aplicao por vez, alm de permitir situaes desejveis como imprimir
um documento enquanto utilizando o editor de textos. Este processo se chama swapping, e para
que isso possa ser feito, o sistema operacional deve fornecer gerenciamento de disco, e um
sistema de arquivos on-line, alm de proteo para que jobs no escrevam sobre jobs que foram
colocados (swapped) em disco.
Hoje, multiprogramao e sistema compartilhado so os temas centrais dos sistemas
operacionais modernos. Os sistemas operacionais mais recentes para microcomputadores
suportam mltiplos usurios e mltiplos programas rodando concorrentemente em tempo
compartilhado. Os sistemas mais conhecidos com essas caractersticas incluem: todas as verses
de UNIX para PCs (UnixWare, SCO Unix, Linux, FreeBSD, Xenix, etc); o Microsoft Windows
3.x, Windows NT, e Windows 95; e o IBM OS/2. Apesar de pouco conhecidos, existem ainda
alguns sistemas operacionais para PCs que rodam programas feitos para o MS-DOS, mas so
multiusurio e multitarefa, como por exemplo o VM/386 e o VirtuOS/386 (produzido por uma
empresa brasileira, a Microbase).

1.2Os Conceitos de Interrupo e Trap


Pode-se dizer que interrupes e traps so as foras que movimentam e dirigem os
sistemas operacionais, pois um sistema operacional s recebe o controle da execuo quando
ocorre alguma interrupo ao trap.
Uma interrupo um sinal de hardware que faz com que o processador

sinalizado interrompa a execuo do programa que vinha executando (guardando informaes


para poder continuar, mais tarde, a execuo desse programa) e passe a executar uma rotina
especfica que trata da interrupo.
Um trap uma instruo especial que, quando executada pelo processador, origina
as mesmas aes ocasionadas por uma interrupo (salvamento de informaes para poder
continuar, mais tarde, a execuo do programa e desvio para uma rotina especfica que trata do
trap). Pode-se dizer que um trap uma interrupo ocasionada por software.
Interrupes podem ser originadas pelos vrios dispositivos perifricos (terminais,
discos, impressoras, etc.), pelo operador (atravs das teclas do console de operao) ou pelo
relgio do sistema. O relgio (timer) um dispositivo de hardware que decrementa
automaticamente o contedo de um registrador ou posio de memria, com uma freqncia
constante, e interrompe a UCP quando o valor decrementado atinge zero. O sistema operacional
garante que ocorrer pelo menos uma interrupo (e ele voltar a trabalhar) dentro de um
intervalo de tempo t, colocando no relgio um valor que demore t unidades de tempo para ser
decrementado at zero. Esta atribuio de valor ao relgio feita imediatamente antes do
sistema operacional entregar a UCP para um programa de usurio.
Uma interrupo no afeta a instruo que est sendo executada pela UCP no
momento em que ela ocorre: a UCP detecta interrupes apenas aps o trmino da execuo de
uma instruo (e antes do incio da execuo da instruo seguinte).
Os computadores possuem instrues para mascarar (desabilitar, inibir) o sistema
de interrupes. Enquanto as interrupes esto mascaradas elas podem ocorrer, mas no so
sentidas pelo processador. Neste caso, as interrupes ficam pendentes (enfileiradas) e s sero
sentidas quando uma instruo que desmascara as mesmas executada.
Conforme j foi dito, os traps so instrues especiais que, quando executadas,
originam aes idnticas s que ocorrem por ocasio de uma interrupo. Pode-se dizer que um
trap uma interrupo prevista, programada no sistema pelo prprio programador. Uma
interrupo, por outro lado, completamente imprevisvel, ocorrendo em pontos que no
podem ser pr-determinados.
Os traps tm a finalidade de permitir aos programas dos usurios a passagem do
controle da execuo para o sistema operacional. Por esse motivo tambm so denominados
chamadas do supervisor ou chamadas do sistema (supervisor call ou system call). Os traps
so necessrios principalmente nos computadores que possuem instrues protegidas
(privilegiadas). Nesses computadores o registrador (palavra) de estado do processador possui
um bit para indicar se a UCP est em estado privilegiado (estado de sistema, estado de

supervisor, estado mestre) ou no privilegiado (estado de usurio, estado de programa, estado


escravo). Sempre que ocorre uma interrupo ou trap, o novo valor carregado no registrador do
estado do processador, indica estado privilegiado de execuo. No estado de supervisor
qualquer instruo pode ser executada e no estado de usurio apenas as instrues no
protegidas podem ser executadas. Exemplos de instrues protegidas so instrues para
desabilitar e habilitar interrupes e instrues para realizar operaes de E/S. Operaes que
envolvam o uso de instrues protegidas s podem ser executadas pelo sistema operacional,
portanto. Quando um programa de usurio necessita executar alguma dessas operaes, o
mesmo deve executar um trap, passando como argumento o nmero que identifica a operao
que est sendo requerida.

2PROCESSOS
O conceito de processo , certamente, o conceito mais importante no estudo de
sistemas operacionais. Para facilitar o entendimento deste conceito, considere-se um
computador

funcionando

em

multiprogramao

(isto

tendo

vrios

programas

simultaneamente ativos na memria). Cada programa em execuo corresponde a um


procedimento (seqncia de instrues) e um conjunto de dados (variveis utilizadas pelo
programa). conveniente ter-se instrues separadas dos dados, pois isso possibilita o
compartilhamento do cdigo do procedimento por vrios programas em execuo (neste caso
diz-se que o procedimento e reentrante ou puro). Se cada programa em execuo possui uma
pilha prpria, ento os dados podem ser criados (alocados) na prpria pilha do programa.
Alm das instrues e dados, cada programa em execuo possui uma rea de
memria correspondente para armazenar os valores dos registradores da UCP, quando o
programa, por algum motivo, no estiver sendo executado. Essa rea de memria conhecida
como registro descritor (ou bloco descritor, bloco de contexto, registro de estado, vetor de
estado) e, alm dos valores dos registradores da UCP, contm outras informaes.
Assim, em um determinado sistema, cada programa em execuo constitui um
processo. Portanto, podemos definir processo como sendo um programa em execuo, o qual
constitudo por uma seqncia de instrues, um conjunto de dados e um registro descritor.
Num ambiente de multiprogramao, quando existe apenas um processador na
instalao, cada processo executado um pouco de cada vez, de forma intercalada. O sistema
operacional aloca a UCP um pouco para cada processo, em uma ordem que no previsvel, em
geral, pois depende de fatores externos aos processos, que variam no tempo (carga do sistema,
por exemplo). Um processo aps receber a UCP, s perde o controle da execuo quando ocorre
uma interrupo ou quando ele executa um trap, requerendo algum servio do sistema
operacional.
As interrupes so transparentes aos processos, pois o efeitos das mesmas apenas
parar, temporariamente, a execuo de um processo, o qual continuar sendo executado, mais
tarde, como se nada tivesse acontecido. Um trap, por outro lado, completamente diferente,
pois bloqueia o processo at que o servio requerido pelo mesmo, ao sistema operacional, seja
realizado.
Deve ser observado que um processo uma entidade completamente definida por si

s, cujas operaes (instrues executadas) se desenvolvem no tempo, em uma ordem que


funo exclusiva dos valores iniciais de suas variveis e dos dados lidos durante a execuo.
Em um sistema com multiprocessamento (com mais de uma UCP), a nica
diferena em relao ao ambiente monoprocessado que o sistema operacional passa a dispor
de mais processadores para alocar os processos, e neste caso tem-se realmente a execuo
simultnea de vrios processos.
Um sistema monoprocessado executando de forma intercalada N processos pode ser
visto como se possusse N processadores virtuais, um para cada processo em execuo. Cada
processador virtual teria 1/N da velocidade do processador real (desprezando-se o overhead
existente na implementao da multiprogramao). O overhead de um sistema operacional o
tempo que o mesmo perde na execuo de suas prprias funes, como por exemplo o tempo
perdido para fazer a multiplexao da UCP entre os processos. o tempo durante o qual o
sistema no est produzindo trabalho til para qualquer usurio.
Tanto no paralelismo fsico (real, com vrias UCP) como no lgico (virtual, uma
UCP compartilhada), as velocidades relativas com que os processos acessaro dados
compartilhados no podem ser previstas. Isto implica em mecanismos de sincronizao entre
processos, como vimos anteriormente com as instrues parbegin/parend.
Processos paralelos so denominados concorrentes ou assncronos e, de acordo
com o tipo de interao existente entre eles, podem ser classificados como disjuntos (no
interativos), quando operam sobre conjuntos distintos de dados, ou interativos, quando tm
acesso a dados comuns. Processos interativos podem ser competitivos, se competirem por
recursos, e/ou cooperantes, se trocarem informaes entre si.
No caso de computaes realizadas por processos interativos, como a ordem das
operaes sobre as variveis compartilhadas pode variar no tempo (pois as velocidades relativas
dos processos dependem de fatores externos que variam no tempo), o resultado da computao
pode no depender somente dos valores iniciais das variveis e dos dados de entrada. Quando o
resultado de uma computao varia de acordo com as velocidades relativas dos processos diz-se
que existe uma condio de corrida (race condition). necessrio evitar condies de corrida
para garantir que o resultado de uma computao no varie entre uma execuo e outra.
Condies de corrida resultam em computaes paralelas errneas, pois cada vez que o
programa for executado (com os mesmos dados) resultados diferentes podero ser obtidos. A
programao de computaes paralelas exige mecanismos de sincronizao entre processos, e
por isso sua programao e depurao bem mais difcil do que em programas tradicionais.
A maioria das linguagens de programao existentes no permite a programao de

computaes paralelas, pois de seus programas origina um nico processo durante a sua
execuo. Tais linguagens so denominadas seqenciais. Linguagens que permitem a
construo de programas que originam vrios processos para serem executados em paralelo so
denominadas linguagens de programao concorrente. Exemplos deste tipo de linguagem
so: Pascal Concorrente, Modula 2, Ada e outras.
A programao concorrente, alm de ser intelectualmente atraente e ser essencial ao
projeto de sistemas operacionais, tambm tem aplicaes na construo de diversos outros tipos
de sistema importantes. Qualquer sistema que deva atender a requisies de servio que possam
ocorrer de forma imprevisvel pode ser organizado, convenientemente, para permitir que cada
tipo de servio seja realizado por um dos processos do sistema. Dessa maneira, diversos
servios podero ser executados simultaneamente e a utilizao dos recursos computacionais
ser, certamente, mais econmica e eficiente. Exemplos de aplicaes deste tipo so sistemas
para controle on-line de informaes (contas bancrias, estoques, etc) e controle de processos
externos (processos industriais, processos qumicos, rotas de foguetes, etc).
Os processos durante suas execues requerem operaes de E/S que so
executadas em dispositivos muito lentos que a UCP, pois os dispositivos perifricos possuem
componentes mecnicos, que funcionam a velocidades muito inferiores dos dispositivos
eletrnicos que funcionam velocidade da luz.
Durante o tempo em que um processo deve ficar esperando a realizao de uma
operao de E/S, a UCP pode ser entregue a outro processo. Dessa forma, a utilizao dos
recursos ser mais completa e, portanto, mais econmica e mais eficiente. Se um processo passa
a maior parte do tempo esperando por dispositivos de E/S, diz-se que o processo limitado por
E/S (I/O-bound). Se, ao contrrio, o processo gasta a maior parte do seu tempo usando a UCP
ele dito limitado por computao (compute-bound ou UCP-bound). Obviamente, processos
I/O-bound devem ter prioridade sobre processos UCP-bound.
Alm de uma melhor utilizao dos recursos, a multiprogramao permite que as
requisies de servio dos usurios sejam atendidas com menores tempos de resposta. Por
exemplo, na situao de um job pequeno e prioritrio ser submetido aps um job demorado j
ter iniciado a execuo, a multiprogramao far com que o job pequeno seja executado em
paralelo e termine muito antes do trmino do job longo.
Os sistemas operacionais acionam os dispositivos de E/S atravs de instrues do
tipo Start I/O (Iniciar E/S). Se o dispositivo uma unidade de disco, por exemplo, a instruo
faz com que um bloco de setores do disco seja lido para a memria principal. Quando o
dispositivo termina a operao, ele manda um sinal de interrupo para a UCP, indicando que

est livre para realizar outra operao. Este sinal faz com que o controle da execuo v para o
sistema operacional, o qual pode acionar o dispositivo para executar outra operao, antes de
devolver a UCP para um processo de usurio.
Durante suas execues os processos dos usurios, ocasionalmente, atravs de
traps, fazem requisies ao sistema operacional (para gravar um setor de disco, por exemplo).
Recebendo a requisio, o sistema operacional bloqueia o processo (deixa de dar tempo de UCP
a ele) at que a operao requerida seja completada. Quando isto acontece o processo
desbloqueado e volta a competir pela UCP com os demais processos.
Quando um processo est realmente usando a UCP, diz-se que o mesmo est no
estado executando (running). Quando est esperando pelo trmino de um servio que requereu,
diz-se que est no estado bloqueado (blocked). Quando o processo tem todas as condies para
ser executado e s no est em execuo porque a UCP est alocada para outro processo, diz-se
que o mesmo est no estado pronto (ready). O sistema operacional mantm uma lista (fila) dos
processos que esto prontos, a chamada lista de processos prontos (ready list ou ready queue).
O diagrama da figura 2.1 mostra como os estados de um processo podem mudar durante a
execuo.

executando

trap

escalonador
interrupo
pronto

bloqueado

interrupo
(concluso do servio)

Figura 2.1 - Estados sucessivos de um processo no sistema


O componente do sistema operacional que, aps o atendimento de uma interrupo
ou trap, escolhe o prximo processo a ser executado denominado escalonador de processos
(scheduler) ou despachador de processos (dispatcher).
Em geral, um trap faz com que o processo fique bloqueado. Entretanto, em algumas
ocasies especiais, quando o sistema operacional pode atender imediatamente a requisio de
servio, o processo pode ser novamente despachado, no ocorrendo o bloqueio.
Quando um job admitido no sistema, um processo correspondente criado e
normalmente inserido no final da ready list. O processo se move gradualmente para a cabea da

ready list, conforme os processos anteriores a ele forem sendo usados pela UCP.
Quando o processo alcana a cabea da lista, e quando a UCP torna-se disponvel, o
processo dado UCP e diz-se que foi feito uma transio do estado ready para o estado
running. A transferncia da UCP para o primeiro processo da ready list chamada dispatching,
e executada pelo dispatcher (ou escalonador). Este transio de estado pode ser ilustrada da
seguinte forma:
Dispatch(processname): ready

running

Para prevenir que um processo monopolize o sistema acidentalmente ou


propositadamente, o S.O. (Sistema Operacional) tem um relgio interno (interrupting clock ou
interval timer) que faz com que o processo execute somente por um intervalo de tempo
especfico ou quantum. Se o processo voluntariamente no libera a UCP antes de expirar seu
intervalo de tempo, o interrupting clock gera uma interrupo, dando ao S.O. o controle
novamente. O S.O. torna o processo corrente (running) em pronto (ready) e torna o primeiro
processo da ready list em corrente. Estas transies de estado so indicadas como:
TimerRunOut(processname):

running

ready

Dispatch(processname):

ready

running

Se um processo corrente iniciar uma operao de I/O antes de expirar o seu


quantum, o processo corrente voluntariamente libera a UCP (isto , ele se bloqueia, ficando
pendente at completar a operao de I/O). Esta transio de estado :
Block(processname):

running

blocked

Quando terminada a operao que fez com que o estado fique bloqueado, este
passa para o estado pronto. A transio que faz tal operao definida como:
WakeUp(processname): blocked

ready

Deste modo podemos definir quatro possveis estados de transio:

Dispatch(processname):

ready

running

TimerRunOut(processname):

running

ready

Block(processname):

running

blocked

WakeUp(processname):

blocked

ready

Note que somente um estado de transio inicializado pelo prprio processo a


transio Block os outros trs estados de transio so inicializados por entidades externas
ao processo.

2.1O Ncleo do Sistema Operacional


Todas as operaes envolvendo processos so controladas por uma poro do
sistema operacional chamada de ncleo, core, ou kernel. O ncleo normalmente representa
somente uma pequena poro do cdigo que em geral tratado como sendo todo o sistema
operacional, mas a parte de cdigo mais intensivamente utilizada. Por essa razo, o ncleo
ordinariamente reside em armazenamento primrio (memria RAM) enquanto outras pores
do sistema operacional so chamadas da memria secundria quando necessrio.
Uma das funes mais importantes includas no ncleo o processamento de
interrupes. Em grandes sistemas multiusurio, uma constante rajada de interrupes
direcionada ao processador. Respostas rpidas a essas interrupes so essenciais para manter
os recursos do sistema bem utilizados, e para prover tempos de resposta aceitveis pelos
usurios.
O ncleo desabilita interrupes enquanto ele responde a uma interrupo;
interrupes so novamente habilitadas aps o processamento de uma interrupo estar
completo. Com um fluxo permanente de interrupes, possvel que o ncleo mantenha
interrupes desabilitadas por um grande poro de tempo; isto pode resultar em respostas
insatisfatrias para interrupes. Entretanto, ncleos so projetados para fazer o mnimo
processamento possvel para cada interrupo, e ento passar o restante do processamento de
uma interrupo para um processo apropriado do sistema que pode terminar de trat-las
enquanto o ncleo continua apto a receber novas interrupes. Isto significa que as interrupes
podem ficar habilitadas durante uma porcentagem muito maior do tempo, e o sistema torna-se
mais eficiente em responder a requisies das aplicaes dos usurios.

2.1.1Um Resumo das Funes do Ncleo


Um sistema operacional normalmente possui cdigo para executar as seguinte
funes:

Manipulao de interrupes;

Criao e destruio de processos;

Troca de contexto de processos;

Desacatamento de processos;

Suspenso e reanimao de processos;

Sincronizao de processos;

Intercomunicao entre processos;

Manipulao de PCBs;

Suporte a atividades de E/S;

Suporte alocao e desalocao de armazenamento;

Suporte ao sistema de arquivos;

Suporte a um mecanismo de chamada/retorno de procedimentos;

Suporte a certas funes do sistema de contabilizao.

2.2Escalonamento de Processos
At agora vimos situaes onde tnhamos dois ou mais processos que poderiam
estar executando a qualquer momento. Estes processos poderiam estar executando, bloqueados,
ou prontos para serem executados. Uma situao adicional, que vimos mais tarde, foi o estado
suspenso.
Quando um ou mais processos esto prontos para serem executados, o sistema
operacional deve decidir qual deles vai ser executado primeiro. A parte do sistema operacional
responsvel por essa deciso chamada escalonador, e o algoritmo usado para tal chamado

de algoritmo de escalonamento. Os algoritmos de escalonamento dos primeiros sistemas,


baseados em cartes perfurados e unidades de fita, era simples: ele simplesmente deveria
executar o prximo job na fita ou leitora de cartes. Em sistemas multi-usurio e de tempo
compartilhado, muitas vezes combinados com jobs batch em background, o algoritmo de
escalonamento mais complexo.
Antes de vermos os algoritmos de escalonamento, vejamos os critrios com os
quais eles devem se preocupar:
1. Justia: fazer com que cada processo ganhe seu tempo justo de CPU;
2. Eficincia: manter a CPU ocupada 100% do tempo (se houver demanda);
3. Tempo de Reposta: minimizar o tempo de resposta para os usurios interativos;
4. Tempo de Turnaround: minimizar o tempo que usurios batch devem esperar pelo
resultado;
5. Throughput: maximizar o nmero de jobs processados por unidade de tempo.

Um pouco de anlise mostrar que alguns desses objetivos so contraditrios. Para


minimizar o tempo de resposta para usurios interativos, o escalonador no deveria rodar
nenhum job batch (exceto entre 3 e 6 da manh, quando os usurios interativos esto
dormindo). Usurios batch no gostaro deste algoritmo, porque ele viola a regra 4.
Uma complicao que os escalonadores devem levar em considerao que cada
processo nico e imprevisvel. Alguns passam a maior parte do tempo esperando por E/S de
arquivos, enquanto outros utilizam a CPU por horas se tiverem chance. Quando o escalonador
inicia a execuo de um processo, ele nunca sabe com certeza quanto tempo vai demorar at
que o processo bloqueie, seja por E/S, seja em um semforo, seja por outro motivo. Para que
um processo no execute tempo demais, praticamente todos os computadores possuem um
mecanismo de relgio (clock) que causa uma interrupo periodicamente. Freqncias de 50 ou
60 Hz so comuns, mas muitas mquinas permitem que o SO especifique esta freqncia. A
cada interrupo de relgio, o sistema operacional assume o controle e decide se o processo
pode continuar executando ou se j ganhou tempo de CPU suficiente. Neste ltimo caso, o
processo suspenso e a CPU dada a outro processo.
A estratgia de permitir ao SO temporariamente suspender a execuo de processos
que estejam querendo executar chamada de escalonamento preemptivo, em contraste com o
mtodo execute at o fim dos antigos sistemas batch. Como vimos at agora, em sistemas
preemptivos um processo pode perder a CPU a qualquer momento para outro processo, sem

qualquer aviso. Isto gera condies de corrida e a necessidade de semforos, contadores de


eventos, monitores, ou algum outro mtodo de comunicao inter-processos. Por outro lado,
uma poltica de deixar um processo rodar enquanto desejar pode fazer com que um processo
que demore uma semana para executar deixe o computador ocupado para os outros usurios
durante este tempo.

2.2.1Escalonamento FCFS ou FIFO


Talvez a disciplina de escalonamento mais simples que exista seja a First-In-FirstOut - FIFO (o primeiro a entrar o primeiro a sair). Vrios autores referem-se a este algoritmo
como FCFS - First-Come-First-Served (o primeiro a chegar o primeiro a ser servido).
Processos so despachados de acordo com sua ordem de chegada na fila de processos prontos
do sistema. Uma vez que um processo ganhe a CPU, ele roda at terminar. FIFO uma
disciplina no preemptiva. Ela justa no sentido de que todos os jobs so executados, e na
ordem de chegada, mas injusta no sentido que grandes jobs podem fazer pequenos jobs
esperarem, e jobs sem grande importncia fazem jobs importantes esperar. FIFO oferece uma
menor varincia nos tempos de resposta e portanto mais previsvel do que outros esquemas.
Ele no til no escalonamento de usurios interativos porque no pode garantir bons tempos
de resposta. Sua natureza essencialmente a de um sistema batch.

2.2.2Escalonamento Round Robin (RR)


Um dos mais antigos, simples, justos, e mais largamente utilizados dos algoritmos
de escalonamento o round robin. Cada processo recebe um intervalo de tempo, chamado
quantum, durante o qual ele pode executar. Se o processo ainda estiver executando ao final do
quantum, a CPU dada a outro processo. Se um processo bloqueou ou terminou antes do final
do quantum, a troca de CPU para outro processo obviamente feita assim que o processo
bloqueia ou termina. Round Robin fcil de implementar. Tudo que o escalonador tem a fazer
manter uma lista de processos runnable (que desejam executar), conforme a figura 2.2(a).
Quando o quantum de um processo acaba, ele colocado no final da lista, conforme a figura
2.2(b).

Processo
corrente

Processo
corrente

Prximo processo

(a)

Prximo processo

(b)

Figura 2.2 - Escalonamento Round Robin. (a) Lista de processos a executar.


(b) Lista de processos a executar depois de terminado o quantum de B

Assim, o algoritmo round robin semelhante ao FIFO, mas com a diferena de que
preemptivo: os processos no executam at o seu final, mas sim durante um certo tempo, um
por vez. Executando sucessivamente em intervalos de tempo o job acaba por terminar sua
execuo em algum momento.
O nico aspecto interessante sobre o algoritmo round robin a durao do
quantum. Mudar de um processo para outro requer um certo tempo para a administrao
salvar e carregar registradores e mapas de memria, atualizar tabelas e listas do SO, etc.
Suponha esta troca de processos ou troca de contexto, como s vezes chamada, dure 5 ms.
Suponha tambm que o quantum est ajustado em 20 ms. Com esses parmetros, aps fazer 20
ms de trabalho til, a CPU ter que gastar 5 ms com troca de contexto. Assim, 20% do tempo de
CPU gasto com o overhead administrativo.
Para melhorar a eficincia da CPU, poderamos ajustar o quantum para digamos,
500 ms. Agora o tempo gasto com troca de contexto menos do que 1 %. Mas considere o que
aconteceria se dez usurios apertassem a tecla <ENTER> exatamente ao mesmo tempo,
disparando cada um processo. Dez processos sero colocados na lista de processo aptos a
executar. Se a CPU estiver ociosa, o primeiro comear imediatamente, o segundo no
comear antes de segundo depois, e assim por diante. O azarado do ltimo processo somente
comear a executar 5 segundos depois do usurio ter apertado <ENTER>, isto se todos os
outros processos tiverem utilizado todo o seu quantum. Muitos usurios vo achar que o tempo
de resposta de 5 segundos para um comando simples muita coisa.
Concluso: ajustar um quantum muito pequeno causa muitas trocas de contexto e
diminui a eficincia da CPU, mas ajust-lo para um valor muito alto causa um tempo de
resposta inaceitvel para pequenas tarefas interativas. Um quantum em torno de 100 ms
freqentemente um valor razovel.

2.2.3Escalonamento com Prioridades


O algoritmo round robin assume que todos os processos so igualmente
importantes. Freqentemente, as pessoas que possuem e operam centros de computao
possuem um pensamento diferente sobre este assunto. Em uma Universidade, por exemplo, as
prioridades de processamento normalmente so para a administrao em primeiro lugar, seguida
de professores, secretrias e finalmente estudantes. A necessidade de se levar em conta fatores
externos nos leva ao escalonamento com prioridades. A idia bsica direta: cada processo
possui uma prioridade associada, e o processo pronto para executar com a maior prioridade
quem ganha o processador.
Para evitar que processos com alta prioridade executem indefinidamente, o
escalonador pode decrementar a prioridade do processo atualmente executando a cada tick de
relgio (isto , a cada interrupo de relgio). Se esta ao fizer com que a prioridade do
processo se torne menor do que a prioridade do processo que possua a segunda mais alta
prioridade, ento uma troca de processos ocorre.
Prioridades podem ser associadas a processos estaticamente ou dinamicamente. Em
um computador militar, por exemplo, processos iniciados por generais deveriam comear com a
prioridade 100, processos de coronis com 90, de majores com 80, de capites com 70, de
tenentes com 60, e assim por diante. Alternaticamente, em um centro de computao comercial
(incomum hoje em dia), jobs de alta prioridade poderiam custar 100 dlares por hora, os de
mdia prioridade a 75 por hora, e os de baixa prioridade a 50 por hora. O sistema operacional
UNIX possui um comando, nice, que permite a um usurio voluntariamente reduzir a prioridade
de um processo seu, de modo a ser gentil (nice) com os outros usurios. Na prtica, ningum
utiliza este comando, pois ele somente permite baixar a prioridade do processo. Entretanto, o
superusurio UNIX pode aumentar a prioridade de processos.
Prioridades podem tambm ser atribudas dinamicamente pelo sistema para atingir
certos objetivos do sistema. Por exemplo, alguns processos so altamente limitados por E/S, e
passam a maior parte do tempo esperando por operaes de E/S. Sempre que um desses
processos quiser a CPU, ele deve obt-la imediatamente, para que possa iniciar sua prxima
requisio de E/S, e deix-la sendo feita em paralelo com outro processo realmente
processando. Fazer com que processos limitados por E/S esperem um bom tempo pela CPU
significa deix-los um tempo demasiado ocupando memria. Um algoritmo simples para prover
um bom servio a um processo limitado por E/S ajustar a sua prioridade para 1/f, onde f a
frao do ltimo quantum de processador que o processo utilizou. Um processo que utilizou

somente 2 ms do seu quantum de 100 ms ganharia uma prioridade 50, enquanto um processo
que executou durante 50 ms antes de bloquear ganharia prioridade 2, e um processo que utilizou
todo o quantum ganharia uma prioridade 1.
freqentemente conveniente agrupar processos em classes de prioridade e utilizar
escalonamento com prioridades entre as classes, mas round robin dentro de cada classe. Por
exemplo, em um sistema com quatro classes de prioridade, o escalonador executa os processos
na classe 4 segundo a poltica round robin at que no haja mais processos na classe 4. Ento
ele passa a executar os processos de classe 3 tambm segundo a poltica round robin, enquanto
houverem processos nesta classe. Ento executa processos da classe 2 e assim por diante. Se as
prioridades no forem ajustadas de tempos em tempos, os processos nas classes de prioridades
mais baixas podem sofrer o fenmeno que chamamos starvation (o processo nunca recebe o
processador, pois sua vez nunca chega).

2.2.4Multilevel Feedback Queues


Quanto um processo ganha a CPU, especialmente quando ele ainda no pde
estabelecer um padro de comportamento, o escalonador no tem idia do quantidade precisa de
tempo de CPU que o processo precisar. Processos limitados por E/S geralmente usam a CPU
brevemente antes de gerar em pedido de E/S. Processos limitados por CPU poderiam utilizar a
CPU por horas se ela estivesse disponvel para eles em um ambiente no preemptivo.
Um mecanismo de escalonamento deveria:

favorecer pequenos jobs;

favorecer jobs limitados por E/S para atingir uma boa utilizao dos dispositivos de
E/S; e

determinar a natureza de um job to rpido quanto possvel e escalonar o job de


acordo.

Multilevel feedback queues (filas multi-nvel com retorno) fornecem uma estrutura
que atinge esses objetivos. O esquema ilustrado na figura 2.3:

Nvel 1
(FIFO)

Usa a
CPU

Trmino

Usa a
CPU

Trmino

Usa a
CPU

Trmino

Preempo

Nvel 2
(FIFO)
Preempo

Nvel n
(round robin)
Preempo
Figura 2.3 - Filas Multinvel com Retorno

Um novo processo entra na rede de filas ao final da fila do topo. Ele se move
atravs desta fila segundo uma poltica FIFO at que ganhe a CPU. Se o job termina ou desiste
da CPU para esperar um trmino de E/S ou outro evento, ele deixa a rede de filas. Se o
quantum expira antes do processo voluntariamente desistir da CPU, o processo colocado de
volta no final da fila um nvel abaixo. O processo avana nesta fila, e em algum momento
atinge a cabea da fila. No momento em que no houverem processos na primeira fila, ele
ganha a CPU novamente. Se ele ainda utiliza todo o quantum, ele vai descendo para as filas de
nveis inferiores. Normalmente, a fila de nvel mais baixo possui uma poltica round robin para
que todos os processos terminem de executar de uma maneira ou outra.
Em muitos sistemas de filas multi-nvel, o quantum dado ao processo conforme ele
se move para as filas de nveis inferiores aumentado. Assim, quanto mais um processo
permanece no sistema de filas, maior o seu quantum. Entretanto ele passa a no ganhar a CPU
com tanta freqncia, porque as filas superiores possuem prioridade maior. Um processo em
uma dada fila no pode executar at que as filas superiores estejam vazias. Um processo em
execuo suspenso em favor de um processo que chegue em uma fila superior.
Considere como tal mecanismo responde a diferentes tipos de processos. O

mecanismo deveria favorecer processos limitados por E/S para atingir boa utilizao dos
dispositivos e bons tempos de resposta aos usurios interativos. Realmente isso funciona porque
um processo limitado por E/S vai entrar na primeira fila e rapidamente ganhar a CPU. O
quantum da primeira fila ajustado para que a maioria dos jobs limitados por E/S tenham
tempo de fazer sua requisio de E/S. Quando o processo faz a requisio de E/S, ele deixa a
rede de filas, tendo recebido o tratamento desejado.
Agora considere um processo limitado por CPU que necessita de um grande tempo
de CPU. Ele entra a rede de filas no nvel mais alto, recebendo rapidamente seu primeiro
quantum de CPU, mas quando ele expira, o processo movido para a fila inferior. Agora o
processo tem prioridade inferior aos da fila superior, mas eventualmente ele recebe a CPU,
ganhando um quantum maior do que o anterior. Conforme o processo ainda precise de CPU, ele
vai caminhando pelas filas, at chegar fila de mais baixo nvel, onde ele circula por uma fila
round robin at que tenha terminado.
Filas Multi-nvel com retorno so ideais para separar processos em categorias
baseadas na sua necessidade por CPU. Em um sistema de tempo compartilhado, cada vez que o
processo deixe a rede de filas, ele pode ser marcado com a identificao do nvel da fila onde
ele esteve pela ltima vez. Quando o processo reentra no sistema de filas, ele pode ser enviado
diretamente para a fila onde ele anteriormente completou sua execuo, de forma que um
processo retornando para as filas no interfira no desempenho dos processos das filas de nveis
mais altos.
Se processos so sempre colocados de volta na rede de filas no nvel mais alto que
eles ocuparam da ltima vez que estiveram no sistema de filas, ser impossvel para o sistema
responder a mudanas no processo, como por exemplo, deixando de ser limitado por CPU para
ser limitado por E/S. Este problema pode ser resolvido marcando tambm o processo com o seu
tempo de permanncia na rede de filas na ltima vez em que l esteve. Assim, quando o
processo reentra no sistema de filas, ele pode ser colocado no lugar correto. Dessa forma, se o
processo est entrando em uma nova fase na qual ela deixa de ser limitado por CPU para ser
limitado por E/S, inicialmente ele vai sofrer uma penalidade pelo sistema, mas da prxima vez
o algoritmo perceber a mudana de comportamento do processo. Uma outra maneira de
responder a mudanas no comportamento de um processo coloc-lo em um nvel de filas cima
do qual esteve se ele voluntariamente desistir da CPU antes do trmino do seu quantum.
O mecanismo de filas multi-nvel com retorno um bom exemplo de um
mecanismo adaptativo, que responde a mudanas de comportamento do sistema que ele
controla. Mecanismos adaptativos normalmente requerem um maior overhead do que os no

adaptativos, mas a sensibilidade a mudanas torna o sistema mais gil e justifica o overhead
adicional.
Uma variao comum deste algoritmo ter os processos circulando em vrias filas
round robin. O processo circula pela primeira fila um certo nmero de vezes, depois desce um
nvel, circulando um nmero maior de vezes, e assim por diante.

2.2.5Escalonamento com Prazos


No escalonamento com prazos certos jobs so escalonados para serem
completados at uma certa data ou hora, ou um prazo. Esses jobs podem ter alta importncia se
entregues tem tempo, ou podem no ter utilidade alguma se terminarem de ser processados
alm do tempo previsto no prazo. O usurio normalmente paga um prmio para ter seu job
completado em tempo. Este tipo de escalonamento complexo por muitas razes:

O usurio deve fornecer os requerimentos precisos de recursos do job previamente.


Tal informao raramente est disponvel;

O sistema deve rodar o job com prazo sem degradar o servio para os outros
usurios;

O sistema deve cuidadosamente planejar seus requerimentos de recursos durante o


prazo. Isto pode ser difcil porque novos jobs podem chegar e adicionar uma
demanda imprevisvel no sistema;

Se muitos jobs com prazos so supostos existirem ao mesmo tempo, o


escalonamento com prazos poderia se tornar to complexo que mtodos sofisticados
de otimizao poderiam ser necessrios para garantir que as metas sejam atingidas;

O intensivo gerenciamento de recursos requerido pelo escalonamento com prazos


pode gerar um overhead substancial. Mesmo que os usurios dos jobs com prazos
estejam aptos a pagar uma taxa suficientemente alta pelos servios recebidos, o
consumo total de recursos do sistema pode se tornar to alto que o resto da
comunidade de usurios poderia ter um servio degradado. Tais conflitos devem ser
considerados cuidadosamente por projetistas de sistemas operacionais.

2.2.6Escalonamento Shortest-Job-First (SJF)


Shortest-job-first (o menor job primeiro) um algoritmo no preemptivo no qual o

job na fila de espera com o menor tempo total estimado de processamento executado em
seguida. SJF reduz o tempo mdio de espera sobre o algoritmo FIFO. Entretanto, os tempos de
espera tem uma varincia muito grande (so mais imprevisveis) do que no algoritmo FIFO,
especialmente para grandes jobs.
SJF favorece jobs pequenos em prejuzo dos jobs maiores. Muitos projetistas
acreditam que quanto mais curto o job, melhor servio ele deveria receber. No h um consenso
universal quanto a isso, especialmente quando prioridades de jobs devem ser consideradas.
SJF seleciona jobs para servio de uma maneira que garante que o prximo job ir
completar e deixar o sistema o mais cedo possvel. Isto tende a reduzir o nmero de jobs
esperando, e tambm reduz o nmero de jobs esperando atrs de grandes jobs. Como resultado,
SJF pode minimizar o tempo mdio de espera conforme eles passam pelo sistema.
O problema bvio com SJF que ele requer um conhecimento preciso de quanto
tempo um job demorar para executar, e esta informao no est usualmente disponvel. O
melhor que SJF pode fazer se basear na estimativa do usurio de tempo de execuo. Em
ambientes de produo onde os mesmos jobs rodam regularmente, pode ser possvel prover
estimativas razoveis. Mas em ambientes de desenvolvimento, os usurios raramente sabem
durante quanto tempo seus programasvo executar.
Basear-se nas estimativas dos usurios possui uma ramificao interessante. Se os
usurios sabem que o sistema est projetado para favorecer jobs com tempos estimados de
execuo pequenos, eles podem fornecer estimativas com valores menores que os reais. O
escalonador pode ser projetado, entretanto, para remover esta tentao. O usurio pode ser
avisado previamente que se o job executar por um tempo maior do que o estimado, ele ser
abortado e o usurio ter que ser cobrado pelo trabalho. Uma segunda opo rodar o job pelo
tempo estimado mais uma pequena percentagem extra, e ento salv-lo no seu estado corrente
de forma que possa ser continuado mais tarde. O usurio, claro, teria que pagar por este
servio, e ainda sofreria um atraso na completude de seu job. Outra soluo rodar o job
durante o tempo estimado a taxas de servios normais, e ento cobrar uma taxa diferenciada
(mais cara) durante o tempo que executar alm do previsto. Dessa forma, o usurio que fornecer
tempos de execuo sub-estimados pode pagar um preo alto por isso.
SJF, assim como FIFO, no preemptivo e portanto no til para sistemas de
tempo compartilhado nos quais tempos razoveis deresposta devem ser garantidos.

2.3Comunicao Entre Processos (IPC)


Processos so concorrentes se eles existem no mesmo tempo. Processos
concorrentes podem funcionar completamente independentes um dos outros, ou eles podem ser
assncronos, o que significa que eles ocasionalmente necessitam de sincronizao e cooperao.
Veremos vrios problemas e tambm solues para o assincronismo de processos
concorrentes.
Processos concorrentes implicam em compartilhamento de recursos do sistema, tais
como arquivos, registros, dispositivos de I/O e reas de memria. Um sistema operacional
multiprogramvel deve fornecer mecanismos de sincronizao de processos, para garantir a
comunicao inter-processos (IPC - Inter-Process Communication) e o acesso a recursos
compartilhados de forma organizada.

2.3.1Processamento Paralelo
Conforme o hardware continua a cair em preos e tamanho, cada vez tornam-se
mais evidentes as tendncias para multiprocessamento, processamento distribudo e mquinas
massivamente paralelas. Se certas operaes podem ser logicamente executadas em paralelo, os
computadores paralelos iro fisicamente execut-las em paralelo, mesmo que o nvel de
paralelismo seja da ordem de milhares ou talvez milhes de atividades concorrentes. Isto pode
resultar em um aumento significativo de performance sobre os computadores seqenciais (com
um nico processador).
O processamento paralelo um assunto interessante e ao mesmo tempo complexo
por vrias razes. As pessoas parecem melhor focalizar sua ateno para uma atividade por vez
do que pensar em paralelo. Um exemplo disso tentar fazer uma pessoa ler dois livros ao
mesmo tempo: uma linha de um, uma linha do outro, e assim por diante.
difcil e denota tempo determinar quais atividades podem e quais no podem ser
executadas em paralelo. Programas paralelos so muito mais difceis de depurar do que
programas seqenciais depois de supostamente consertar um bug, praticamente impossvel
reproduzir a seqncia exata de eventos que fez com que o erro aparecesse, dessa forma ento
impossibilitando certificar, com certeza, de que o erro foi corretamente removido.
Processos assncronos podem ocasionalmente interagir um com o outro, e essas
interaes podem ser complexas.
Finalmente, muito mais difcil provas que programas paralelos esto corretos, do

que programas seqenciais. A prova da corretude de programas envolve geralmente testes


exaustivos, e as possibilidades de execuo em programas paralelos podem ser infinitas, sendo
impossvel a exausto de todas as possibilidades.

2.3.1.1Comandos PARBEGIN e PAREND (Dijkstra)


Vrias linguagens de programao paralela tm aparecido na literatura. Estas
geralmente envolvem um par de comandos, da seguinte forma:

Um comando indicando que a execuo seqencial passa a ser dividida em vrias


seqncias de execuo em paralelo (linhas de controle ou execuo); e

Um comando indicando que certas seqncias de execuo paralelas devem se


juntar para a execuo seqencial continuar.

Estes comandos ocorrem sempre aos pares e so comumente chamados


parbegin/parend (incio e fim de execuo paralela), ou cobegin/coend (incio e fim de
execuo concorrente). Utilizaremos parbegin/parend, conforme sugerido por Dijkstra (1965),
na seguinte forma geral:
parbegin
comando-1;
comando-2;
.
.
.
comando-n
parend

Figura 2.4 - Forma geral dos comandos parbegin/parend.


Suponhamos que um programa em execuo encontre a construo parbegin. Isto
vai causar uma diviso de controle da execuo entre os vrios comandos seguintes,
possivelmente entre vrios processadores (se a mquina for multiprocessada). Quando o
comando parend atingido, a execuo s prossegue at que todos os sub-comandos
concorrentes tenham terminado. A partir deste ponto, a execuo passa novamente a ser
seqencial.
Considere o seguinte exemplo, onde o operador ** o operador de exponenciao:
x := (-b + (b ** 2 - 4 * a * c) ** .5) / (2 * a)

Em uma mquina com processamento seqencial, a expresso acima seria


desmembrada em vrias aes:

b ** 2

4 * a

(4 * a) * c

(b ** 2) - (4 * a * c)

(b ** 2 - 4 * a *c) ** .5

-b

(-b) + ((b ** 2 - 4 * a * c) ** .5)

2 * a

(-b + (b ** 2 - 4 * a * c) ** .5) / (2 * a)

Em um sistema que suporte processamento paralelo, a mesma expresso deveria ser


executada da seguinte maneira:
1

parbegin
temp1 := -b;
temp2 := b ** 2;
temp3 := 4 * a;
temp4 := 2 * a
parend;

temp5 := temp3 * c;

temp5 := temp2 - temp5;

temp5 := temp5 ** .5;

temp5 := temp1 + temp5;

x := temp5 / temp4

Neste caso, as operaes entre o parbegin e o parend so executadas em paralelo


as operaes restantes devem ser executadas seqencialmente. Pela execuo das instrues em
paralelo, possvel reduzir substancialmente o tempo real de execuo do programa.

2.3.1.2Comandos FORK e JOIN (Conway e Dennis)


Utilizados pelo sistema operacional UNIX, e tambm implementados em algumas
linguagens de programao, como PL/1.
Considere o trecho de cdigo da figura 2.5:
program A;
...
fork B;
...
join B;
...
end.

program B;
...
...
...
end.

Figura 2.5 - Cdigo utilizando FORK e JOIN


O programa A comea a ser processado e, ao encontrar o comando FORK, faz com
que seja criado um outro processo (ou subprocesso) para a execuo do programa B,
concorrentemente a A. O comando JOIN permite que o programa A sincronize-se com B, ou
seja, quando o programa A encontrar o comando JOIN, s continuar a ser processado aps o
trmino de B.

2.3.2Excluso Mtua
Considere um sistema com muitos terminais em tempo compartilhado. Assuma que
os usurios terminam cada linha de texto que eles digitam com a tecla <ENTER>. Suponha que
seja desejvel monitorar continuamente o nmero total de linhas que os usurios entraram no
sistema desde o incio do dia. Assuma que cada terminal de usurio seja monitorado por um
processo diferente. Toda vez que um destes processos recebe uma linha do terminal, ele
incrementa de 1 uma varivel global compartilhada do sistema, chamada LINHAS. Considere o
que aconteceria se dois processos tentassem incrementar LINHAS simultaneamente. Assuma
que cada processo possui sua prpria cpia do seguinte cdigo:
LOAD
ADD
STORE

LINHAS
1
LINHAS

; L a varivel linhas no registrador acumulador


; Incrementa o registrador acumulador
; Armazena o contedo do acumulador na varivel

Suponhamos que LINHAS tenha o valor atual 21687. Agora suponhamos que o
primeiro processo execute as instrues LOAD e ADD, deixando ento o valor 21688 no
acumulador. Ento o processo perde o processador (aps o trmino de seu quantum) para o
segundo processo. O segundo processo ento executa as trs instrues, fazendo com que a
varivel linhas tenha o valor 21688. Ele ento perde o processador para o primeiro processo que
continua executando de onde tinha parado, e portanto executando a instruo STORE, e
armazenando 21688 na varivel LINHAS. Devido falta de comunicao entre os processos, o
sistema deixou de contar uma linha o valor correto seria 21689.
O problema est em dois ou mais processos escreverem em uma varivel
compartilhada. Vrias processos poderiam estar lendo uma varivel compartilhada sem
problemas. Entretanto, quando um processo l uma varivel que outro processo est
escrevendo, ou quando um processo tenta escrever em uma varivel que outro processo tambm
esteja escrevendo, resultados inesperados podem acontecer.
O problema pode ser resolvido dando a cada processo acesso exclusivo varivel

LINHAS. Enquanto um processo incrementa a varivel, todos os outros processos desejando


faz-lo no mesmo instante devero esperar; quando o primeiro processo terminar o acesso
varivel compartilhada, um dos processos passa a ter acesso varivel. Assim, cada processo
acessando a varivel exclui todos outros de faz-lo simultaneamente. Isto chamado de
excluso mtua. Como veremos, os processos em espera devero ser gerenciados de forma a
esperarem um tempo razoavelmente curto.

2.3.3Regies Crticas
A excluso mtua somente precisa estar presente nos instantes em que os processos
acessam dados compartilhados modificveis quando os processos esto executando
operaes que no conflitam um com o outro, eles deveriam ser liberados para processarem
concorrentemente. Quando um processo est acessando dados compartilhados modificveis,
dito que o processo est em sua regio crtica ou seo crtica.
Fica claro, que para evitarmos problemas como o mostrando acima, necessrio
garantir que quando um processo est em sua regio crtica, todos os outros processos (pelo
menos aqueles que acessam a mesma varivel compartilhada modificvel) sejam excludos de
suas respectivas regies crticas.
Enquanto um processo est em sua regio crtica, outros processos podem
certamente continuar sua execuo fora de suas regies crticas. Quando um processo deixa sua
regio crtica, um dos processos esperando para entrar em sua prpria regio crtica pode
prosseguir. Garantir a excluso mtua um dos principais problemas em programao
concorrente. Muitas solues foram propostas: algumas baseadas em software e outras baseadas
em hardware; algumas em baixo nvel, outras em alto nvel; algumas requerendo cooperao
voluntria entre processos, outras exigindo uma rgida aderncia a protocolos estritos.
Um processo dentro de uma regio crtica est em um estado muito especial. O
processo possui acesso exclusivo aos dados compartilhados modificveis, e todos os outros
processos desejando acess-los devem esperar. Assim, regies crticas devem executar o mais
rpido possvel, um processo no deve passar para o estado bloqueado dentro da regio crtica,
e regies crticas devem ser cuidadosamente codificadas (para evitar, por exemplo, loops
infinitos).

2.3.4Primitivas de Excluso Mtua


O programa concorrente apresentado a seguir, implementa o mecanismo de
contagem de linhas de texto digitadas pelos usurios, descrito anteriormente. A linguagem
utilizada uma pseudo-linguagem com sintaxe semelhante linguagem Pascal, mas com
mecanismos de paralelismo. Para maior simplicidade, vamos assumir que somente dois
processos concorrentes nos programas apresentados nesta e nas sees seguintes. Manipular n
processos concorrentes consideravelmente mais complexo.
program excluso_mtua;
var linhas_digitadas: integer;
procedure processo_um;
while true do
begin
leia_prxima_linha_do_terminal;
entermutex;
linhas_digitadas := linhas_digitadas + 1;
exitmutex;
processe_a_linha;
end;
procedure processo_dois;
while true do
begin
leia_prxima_linha_do_terminal;
entermutex;
linhas_digitadas := linhas_digitadas + 1;
exitmutex;
processe_a_linha;
end;
begin
linhas_digitadas := 0;
parbegin
processo_um;
processo_dois;
parend;
end.

O par de construes entermutex / exitmutex introduzidos no exemplo delimitam


o cdigo da regio crtica de cada processo. Essas operaes so normalmente chamadas de
primitivas de excluso mtua, e cada linguagem que as suporte pode implement-las sua
maneira.
No caso de dois processos, como no exemplo, as primitivas operam da seguinte
maneira. Quando o processo_um executa entermutex, se o processo_dois no est em sua
regio crtica, ento o processo _um entra em sua regio crtica, acessa a varivel e ento
executa exitmutex para indicar que ele deixou sua regio crtica.
Se o processo_dois est em sua regio crtica quando o processo_um executa
entermutex, ento o processo_um espera at que o processo_dois execute exitmutex. Ento o
processo_um pode prosseguir e entrar em sua regio crtica.
Se tanto o processo_um como o processo_dois executam simultaneamente

entermutex, ento somente liberado para prosseguir, enquanto o outro permanece esperando.
Por enquanto, vamos assumir que o vencedor escolhido aleatoriamente pelo sistema
operacional.

2.3.5Implementao de Primitivas de Excluso Mtua


A implementao das primitivas entermutex (entrada no cdigo de excluso
mtua) e exitmutex (sada do cdigo de excluso mtua)deve satisfazer as seguintes restries:

A soluo deve ser implementada puramente em software em uma mquina sem


suporte a instrues especficas para excluso mtua.

Cada instruo da mquina executada indivisivelmente, isto , uma vez que uma
instruo comea a ser executada, ela termina sem nenhuma interrupo.

Se mltiplos processadores tentam acessar o mesmo item de dados, assumimos que


um recurso de hardware chamado storage interlock (interbloqueio de
armazenamento) resolve qualquer conflito. O storage interlock seqencializa as
referncias conflitantes a um item de dados, isto , as referncias acontecem uma
por vez. Assumimos tambm que as vrias referncias so servidas em uma ordem
aleatria.

Nenhuma suposio deve ser feita sobre as velocidades relativas dos processos
concorrentes assncronos.

Processos operando fora de suas regies crticas no podem evitar que outros
processos entrem em suas prprias regies crticas.

Processos no devem ter sua vez de entrar em sua regio crtica indefinidamente
adiada.

Uma implementao elegante em software de excluso mtua foi pela primeira vez
apresentada pelo matemtico alemo Dekker. Esta soluo implementa excluso mtua com
espera ocupada (busy wait), pois os processos ficam em um loop infinito fazendo testes at
conseguirem entrar nas suas regies crticas. O algoritmo de Dekker foi analisado e apresentado
por diversos autores da rea de sistemas operacionais. Um deles, G. L. Peterson, apresentou
mais tarde um algoritmo mais simplificado do algoritmo original de Dekker.
Entretanto, a soluo de Dekker somente funciona para excluso mtua entre dois

processos. Outras solues foram inventadas, e contam com algum suporte do sistema
operacional, o que facilita a vida do programador. Vejamos a seguir estas solues.

2.3.6Excluso Mtua para N Processos


Em 1965, Dijkstra foi o primeiro a apresentar uma soluo em software para a
implementao de primitivas de excluso mtua para n processos. Knuth respondeu em 1966
com uma soluo que eliminou a possibilidade de adiamento indefinido existente no algoritmo
de Dijkstra, mas que ainda permitia que um processo pudesse sofrer um longo atraso na hora de
entrar em sua regio crtica.
Isto desencadeou vrias tentativas de encontrar algoritmos com menores atrasos.
Eisenberg e McGuire (1972) apresentaram uma soluo que garantia que em uma situao com
n processos, um desses processos conseguiria entrar em sua regio crtica com no mximo n - 1
tentativas.
Em 1974, Lamport desenvolveu uma soluo que particularmente aplicvel a
sistemas de processamento distribudo. O algoritmo utiliza um sistema do tipo pegue uma
senha, da mesma forma que algumas padarias da poca utilizavam, e por isso foi chamado de
Lamports Bakery Algorithm (algoritmo de padaria de Lamport).
Brinch Hansen (1978) tambm discute controle de concorrncia entre processos
distribudos. Burns, et alli (1982), oferece uma soluo utilizando uma nica varivel
compartilhada. Carvalho e Roucairol (1983) discutem a garantia de excluso mtua em redes de
computadores.

2.3.7Semforos
Dijkstra conseguiu abstrair as principais noes de excluso mtua em seu conceito
de semforos. Um semforo uma varivel protegida cujo valor somente pode ser acessado e
alterado pelas operaes P e V, e por uma operao de inicializao que chamaremos
inicializa_semforo. Semforos binrios podem assumir somente os valores 0 ou 1.
Semforos contadores (tambm chamados de semforos genricos) podem assumir somente
valores inteiros no negativos.

A operao P no semforo S, denotada por P(S), funciona da seguinte maneira:


if S > 0 then
S := S - 1
else
(espera no semforo S)

A operao V no semforo S, denotada por V(S), funciona da seguinte maneira:


if (um ou mais processos esto esperando em S) then
(deixe um desses processos continuar)
else
S := S + 1;

Ns podemos assumir que existe uma poltica de enfileiramento FIFO (first-infirst-out o primeiro a entrar o primeiro a sair) para os processos esperando para uma
operao P(S) completar.
Assim como testandset, as operaes P e V so indivisveis. A excluso mtua no
semforo S garantida pelas operaes P(S) e V(S). Se vrios processos tentam executar P(S)
simultaneamente, somente um deles poder prosseguir. Os outros ficaro esperando, mas a
implementao de P e V garante que os processos no sofreroadiamento indefinido.
Semforos e operaes com semforos podem ser implementados tanto em
software quanto em hardware. Eles so comumente implementados no ncleo do sistema
operacional, onde a mudana de estado dos processos controlada. O exemplo a seguir ilustra o
uso de semforos para implementar excluso mtua. Neste exemplo, P(ativo) equivalente a
entermutex e V(ativo) equivalente a exitmutex.
program exemplo_semforo;
var ativo: semaphore;
procedure processo_um;
begin
while true do
begin
algumas_funcoes_um;
P(ativo);
regiao_critica_um;
V(ativo);
outras_funcoes_um;
end
end;
procedure processo_dois;
begin
while true do
begin
algumas_funcoes_dois;
P(ativo);
regiao_critica_dois;
V(ativo);
outras_funcoes_dois;

end
end;
begin
inicializa_semaforo(ativo, 1);
parbegin
processo_um;
processo_dois
parend
end.

2.3.7.1Sincronizao de Processos com Semforos


Quando um processo invoca uma requisio de E/S, ele se auto-bloqueia para
esperar o trmino da operao de E/S. Alguns outros processos devem acordar o processo
bloqueado. Tal interao um exemplo de um protocolo bloqueia/acorda (block/wakeup).
Mais genericamente, suponha que um processo queira ser notificado sobre a
ocorrncia de um evento particular. Suponha que algum outro processo seja capaz de detectar
que esse evento ocorreu. O exemplo seguinte mostra como operaes de semforo podem ser
usadas para implementar um mecanismo de sincronizao simples block/wakeup.
program block_wakeup;
var evento_de_interesse: semaphore;
procedure processo_um;
begin
algumas_funcoes_um;
P(evento_de_interesse);
outras_funcoes_um
end;
procedure processo_dois;
begin
algumas_funcoes_dois;
V(evento_de_interesse);
outras_funcoes_dois
end;

begin
inicializa_semaforo(evento_de_interesse, 0);
parbegin
processo_um;
processo_dois
parend
end.

processo_um

executa

algumas_funcoes_um

ento

executa

P(evento_de_interesse) para esperar (wait) at que o evento acontea. O semforo foi


inicializado em zero para que inicialmente o processo espere. Eventualmente o processo_dois
executa V(evento_de_interesse) para sinalizar (signal) que o evento ocorreu. Isto permite que o

processo_um prossiga (com o semforo ainda em zero).


Note que esse mecanismo funciona mesmo que o processo_dois detecte e sinalize o
evento com V(evento_de_interesse) antes que o processo_um execute P(evento_de_interesse)
o semforo ser incrementado de 0 para 1, ento P(evento_de_interesse) ir simplesmente
decrementar o semforo de 1 para 0, e o processo_um ir presseguir sem ter que esperar pelo
evento.

2.3.7.2A Relao Produtor-Consumidor


Em um programa seqencial, quando um procedimento chama um outro e lhe passa
dados como parmetros, os procedimentos so partes de um nico processo eles no operam
concorrentemente. Mas quando um processo passa dados para outro processo, os problemas so
mais complexos. Tal transmisso um exemplo de comunicao inter-processos (interprocess
communication - IPC).
Considere a seguinte relao produtor-consumidor. Suponha que um processo, um
produtor, esteja gerando informao que um segundo processo, o consumidor, esteja
utilizando. Suponha que eles se comunicam por uma nica varivel inteira compartilhada,
chamada numero. O produtor faz alguns clculos e ento escreve o resultado em numero; o
consumidor l o dado de numero e o imprime.
possvel que os processos produtor e consumidor executem sem problemas, ou
que suas velocidades sejam incompatveis. Se cada vez que o produtor depositar um resultado
em numero o consumidor puder l-lo e imprimi-lo, ento o resultado impresso certamente
representar a seqncia de nmeros gerados pelo produtor.
Mas suponha que as velocidades dos processos sejam incompatveis. Se o
consumidor estiver operando mais rpido que o produtor, o consumidor poderia ler e imprimir o
mesmo nmero duas vezes (ou talvez vrias vezes) antes que o produtor depositasse o prximo
nmero. Se o produtor estiver operando mais rpido que o consumidor, o produtor poderia
sobrescrever seu resultado prvio sem que o consumidor tivesse a chance de l-lo e imprimi-lo;
um produtor rpido poderia de fato fazer isto vrias vezes de forma que vrios resultados
poderiam ser perdidos.
Obviamente, o comportamento que desejamos aqui que o produtor e o
consumidor operem de tal forma que dados escritos para numero nunca sejam perdidos ou
duplicados. A garantia de tal comportamento um exemplo de sincronizao de processos.

Abaixo temos um exemplo de um programa concorrente que utiliza operaes com


semforos para implementar uma relao produtor-consumidor.
program relacao_produtor_consumidor;
var numero: integer;
numero_depositado: semaphore;
numero_retirado: semaphore;
procedure processo_produtor;
var proximo_resultado: integer;
begin
while true do
begin
calcule_proximo_resultado;
P(numero_retirado);
numero := proximo_resultado;
V(numero_depositado)
end
end;
procedure processo_consumidor;
var proximo_resultado: integer;
begin
while true do
begin
calcule_proximo_resultado;
P(numero_depositado);
proximo_resultado := numero;
V(numero_retirado);
write(proximo_resultado)
end
end;
begin
inicializa_semaforo(numero_depositado, 0);
inicializa_semaforo(numero_retirado, 1);
parbegin
processo_produtor;
processo_consumidor
parend
end.

Dois semforos foram utilizados: numero_depositado sinalizado (operao V)


pelo produtor e testado (operao P) pelo consumidor; o consumidor no pode prosseguir at
que um nmero seja depositado em numero. O processo consumidor sinaliza (operao V)
numero_retirado e o produtor o testa (operao P); o produtor no pode prosseguir at que um
resultado existente em numero seja retirado. Os ajustes iniciais dos semforos foram o
produtor a depositar um valor em numero antes que o consumidor possa prosseguir. Note que o
uso de semforos neste programa fora a sincronizao passo a passo; isto aceitvel porque s
existe uma nica varivel compartilhada. comum em relaes produtor-consumidor que se
tenha um buffer com espao para vrias variveis. Com tal arranjo, o produtor e o consumidor
no precisam executar mesma velocidade na sincronizao passo a passo. Ao contrrio, um
produtor rpido pode depositar diversos valores enquanto o consumidor est inativo, e um
consumidor rpido pode retirar diversos valores enquanto o produtor est inativo.

Investigaremos este tipo de relao com mais detalhes no futuro.

2.3.7.3Semforos Contadores
Semforos contadores so particularmente teis quando um recurso deve ser
alocado a partir de um pool (agrupamento) de recursos idnticos. O semforo inicializado com
o nmero de recursos no agrupamento. Cada operao P decrementa o semforo de 1, indicando
que um recurso foi removido do agrupamento e est em uso por um processo. Cada operao V
incrementa o semforo de 1, indicando que um processo retornou um recurso ao agrupamento, e
o recurso pode ser realocado para outro processo. Se uma operao P executada quando o
semforo possui o valor zero, ento o processo deve esperar at que um recurso seja liberado
com uma operao V.

2.3.7.4Implementando Semforos, P e V
Dado o algoritmo de Dekker e a disponibilidade de uma instruo de mquina
testandset, praticamente direto implementar P e V utilizando busy waiting. Mas esta tcnica
pode no ser boa porque desperdia recursos de CPU.
J vimos em sees anteriores os mecanismos de troca de estados de processos
implementados no ncleo do sistema operacional. Observamos que um processo requisitando
uma operao de E/S voluntariamente se bloqueia esperando que a operao de E/S seja
completada. O processo bloqueado no espera de forma ocupada (busy wait), isto , no fica
processando continuamente um loop de teste para verificar se a operao de E/S j terminou. Ao
contrrio, ele libera o processador, e o ncleo do sistema operacional o coloca (coloca seu PCB)
na lista de processos bloqueados. O processo permanece dormindo at que ele seja
acordado pelo ncleo do sistema operacional quando sua operao de E/S estiver completa,
tirando-o da lista de processos bloqueados e colocando-o na lista de processos prontos para
execuo.
Operaes com semforos tambm podem ser implementadas no ncleo do sistema
operacional para evitar a espera ocupada (busy waiting). Um semforo implementado como
uma varivel protegida e uma fila na qual processos podem esperar por operaes V. Quando
um processo tenta executar uma operao P em um semforo cujo valor corrente seja zero, o
processo libera o processador e se bloqueia para esperar uma operao V no semforo. O ncleo
do SO coloca o PCB do processo na fila de processos esperando naquele semforo. Note que

alguns sistemas implementam uma fila de espera do tipo FIFO, enquanto outros utilizam filas
com prioridades ou mesmo outras disciplinas. Em seguida, o ncleo do SO ento realoca o
processador para o prximo processo pronto paraexecuo.
Em algum momento, nosso processo na fila do semforo vai chegar primeira
posio da fila. A prximo operao V vai remover o processo da fila do semforo e coloc-lo
na lista de processos prontos. claro que processos tentando simultaneamente executar
operaes P e V em um semforo ganharo acesso exclusivo ao semforo pelo ncleo do SO.
Vale notar o caso especial de que em sistemas com um nico processador, a
indivisibilidade de P e V pode ser garantida simplesmente desabilitando interrupes enquanto
operaes P e V esto manipulando o semforo. Isto previne que o processador seja roubado
at que a manipulao do semforo esteja completa. Neste momento as interrupes podero ser
novamente habilitadas.
No ncleo de um sistema multiprocessado, a um dos processadores pode ser dada a
tarefa de controlar a lista de processos prontos e determinar que processadores executam quais
processos. Uma outra abordagem para implementar o ncleo para um sistema multiprocessado
controlar o acesso (via busy waiting) a uma lista de pronto compartilhada. Um ncleo de um
sistema distribudo poderia ter um processador controlando a lista de pronto, mas normalmente
cada processador gerenciaria sua prpria lista de pronto. Portanto, cada processador
essencialmente possui seu prprio ncleo. Conforme um processo migra entre os vrios
processadores em um sistema distribudo, o controle daquele processo passado de um ncleo
para outro.

2.3.8Monitores
A comunicao interprocessos utilizando semforos e contadores de eventos parece
ser a soluo definitiva. Entretanto, se analisarmos mais diretamente estas tcnicas, veremos
que elas possuem alguns problemas:

So to primitivos que difcil expressar solues para problemas de concorrncia


mais complexos;

seu uso em programas concorrentes aumenta a j difcil tarefa de provar a corretude


de programas;

o mau uso dessas primitivas, tanto de forma acidental como maliciosa, poderia
corromper a operao do sistema concorrente.

Particularmente com semforos, alguns outros problemas podem ocorrer:

Se a operao P for omitida, no garantida a excluso mtua;

se a operao V for omitida, tarefas esperando em uma operao P entrariam em


deadlock;

uma vez que a operao P usada e o processo fica nela bloqueado, ele no pode
desistir e tomar um curso de ao alternativo enquanto o semforo estiver em uso;

um processo s pode esperar em um semforo por vez, o que pode lev-lo a


deadlock em algumas situaes de alocao de recursos.

Assim, podemos perceber que o programador deve ser extremamente cuidadoso ao


utilizar semforos, por exemplo. Um sbito erro e tudo poder parar de funcionar sem nenhuma
explicao. como programar em linguagem assembly, s que pior, porque os erros, condies
de corrida, deadlocks, e outras formas de comportamento imprevisvel no podem ser
reproduzidos para testar programas.
Para tornar mais fcil a escrita de programas corretos, Hoare (1974) e Brinch
Hansen (1975) propuseram uma primitiva de sincronizao de alto nvel chamada de monitor.
Um monitor uma coleo de procedimentos, variveis, e estruturas de dados que so todos
agrupados em um tipo especial de mdulo ou pacote. Processos podem chamar os
procedimentos em um monitor sempre que o desejarem, mas eles no podem diretamente
acessar diretamente as estruturas de dados internas do monitor atravs de procedimentos
declarados fora do monitor. O exemplo abaixo ilustra um monitor escrito em nossa linguagem
imaginria, semelhante a Pascal:
monitor exemplo;
var i: integer;
c: condition; { varivel de condio }
procedure produtor(x: integer);
begin
.
.
.
end;

procedure consumidor(x: integer);


begin
.
.

.
end;
end monitor;

Monitores possuem uma importante propriedade que os torna til para atingir
excluso mtua: somente um processo pode estar ativo em um monitor em qualquer momento.
Monitores so uma construo da prpria linguagem de programao utilizada, de forma que o
compilador sabe que eles so especiais, e pode manipular chamadas a procedimentos dos
monitores de forma diferente da qual manipula outras chamadas de procedimentos.
Tipicamente, quando um processo chama um procedimento de um monitor, as primeiras
instrues do procedimento iro checar se algum outro processo est ativo dentro do monitor.
Se isto acontecer, o processo que chamou o procedimento ser suspenso at que outro processo
tenha deixado o monitor. Se nenhum outro processo estiver usando o monitor, o processo que
chamou o procedimento poder entrar.
Fica a cargo do compilador implementar a excluso mtua nas entradas do monitor,
mas comum utilizar semforos binrios. Uma vez que o compilador, e no o programador,
quem faz os arranjos para a excluso mtua, muito menos provvel que alguma coisa d
errado. Em qualquer situao, a pessoa escrevendo o monitor no precisa saber como o
compilador faz os arranjos para excluso mtua. suficiente saber que ao transformar todas as
regies crticas em procedimentos de monitor, dois processos jamais executaro suas regies
crticas simultaneamente.
Apesar de monitores proverem uma maneira fcil de se conseguir excluso mtua,
como acabamos de dizer, isto no suficiente. necessrio tambm que se tenha um meio de
fazer os processos bloquearem quando eles no podem prosseguir. Considere o seguinte
exemplo da relao produtor-consumidor:
program produtor_consumidor;
const N = 100;
var cont: integer;

procedure produtor;
begin
while true do begin
produz_item;
{ produz um item de dado }
if (cont = N) then
suspend;
{ se o buffer esta cheio, entra em suspensao }
entra_item;
{ coloca o item produzido no buffer }
cont := cont + 1;
if (cont = 1) then
resume (consumidor); { se o buffer estava vazio, acorda o consumidor}
end;
end;

procedure consumidor;
begin
while true do begin
if (cont = 0) then
suspend;
{ se o buffer esta vazio, entra em suspensao }
remove_item;
{ remove o item do buffer }
cont := cont - 1;
if (cont = N - 1) then
resume (produtor); { se o buffer estava cheio, acorda o produtor }
consome_item;
{ imprime o item }
end;
end;
begin
cont := 0;
parbegin
produtor;
consumidor;
parend;
end.

No exemplo acima utilizamos as chamadas de sistema suspend e resume. Quando


um processo percebe que no poder continuar processando, pois depende de outra condio
para continuar, ele se auto suspende atravs de um suspend. Quando o outro processo percebe
que j existe condio para o processo suspenso continuar, ele o acorda com um resume.
Analisando o exemplo, podemos perceber que ali existe uma condio de corrida.
Ela pode ocorrer porque o acesso varivel cont irrestrito. A seguinte situao poderia
ocorrer. O buffer est vazio e o consumidor acabou de ler o valor de cont para checar se era 0.
Neste exato momento, o escalonador decide parar a execuo do consumidor e comea a
executar o produtor. O produtor entra com um item no buffer, incrementa cont, e percebe que
agora cont vale 1. Percebendo que cont era anteriormente 0, e que portanto o consumidor
deveria estar suspenso, o produtor chama resume para acordar o consumidor.
Mas o consumidor na verdade no estava suspenso, e o sinal de resume perdido.
Quando o consumidor novamente ganha o processador, ele testa o valor de cont que ele j havia
lido como sendo 0, e ento chama suspend, entrando em estado suspenso. Mais tarde o
produtor ir completar todo o buffer e tambm chamar suspend, ficando ambos os processos
suspensos para sempre.

Poderamos resolver este problema utilizando monitores, simplesmente colocando


os testes para buffer cheio e buffer vazio dentro de procedimentos de monitor, mas como o
produtor poderia se bloquear se encontrasse o buffer cheio?
A soluo recai na introduo do conceito de variveis de condio, juntamente
com duas operaes sobre elas, wait e signal. Quando um procedimento de monitor descobre

que ele no pode continuar (por exemplo, o produtor encontra o buffer cheio), ele executa um
wait em alguma varivel de condio, digamos, cheio. Esta ao faz com que o processo que
chamou o procedimento bloqueie. Isto tambm permite que outro processo que tenha sido
anteriormente proibido de entrar no monitor possa agora entrar.
Este outro processo, por exemplo, o consumidor, pode acordar seu parceiro
suspenso executando um signal na varivel de condio na qual seu parceiro est esperando.
Para evitar que dois processos estejam ativos no monitor ao mesmo tempo, preciso uma regra
que diga o que acontece aps um signal. Hoare props deixar o processo recm-acordado
prosseguir, suspendendo o outro. Brinch Hansen props que o processo que chame signal deve
deixar o monitor imediatamente. Em outras palavras, uma chamada a signal deve aparecer
somente como o ltimo comando em um procedimento de monitor. Utilizaremos a proposta de
Brinch Hansen por ser conceitualmente mais simples e tambm mais fcil de implementar. Se
um comando signal executado em uma varivel na qual vrios processos esto esperando,
somente um deles, determinado pelo escalonador do sistema, acordado.
Um esqueleto do problema produtor-consumidor utilizando monitores
apresentado a seguir:

monitor ProdutorConsumidor;
var cheio, vazio: condition; { variveis de condio }
cont: integer;
procedure colocar;
begin
if cont = N then
wait(cheio);
entra_item;
cont := cont + 1;
if cont = 1 then
signal(vazio);
end;
procedure remover;
begin
if cont = 0 then
wait(vazio);
remove_item;
cont := cont - 1;
if cont = N - 1 then
signal(cheio);
end;
count := 0;
end monitor;
procedure produtor;
begin
while true do begin
produz_item;
ProdutorConsumidor.colocar;
end
end;

procedure consumidor;
begin
while true do begin
ProdutorConsumidor.remover;
consome_item;
end
end;

Pode parecer que as operaes wait e signal paream similares s operaes


suspend e resume. De fato, elas so muito similares, mas com uma diferena crucial: suspend
e resume falharam porque enquanto um processo tentava ficar suspenso, o outro tentava
acord-lo. Com monitores, isso no pode acontecer. A excluso mtua automtica nos
procedimentos do monitor garante isso pois, se por exemplo, o produtor dentro de um
procedimento do monitor descobre que o buffer est cheio, ele ser capaz de completar a
operao wait sem se preocupar com a possibilidade de que o escalonador venha a dar o
processador ao consumidor antes que a operao wait complete. O consumidor no poder nem
sequer entrar no monitor antes que a operao wait tenha terminado e o processo produtor tenha
sido marcado como suspenso pelo sistema.
Ao fazer a excluso mtua de regies crticas automtica, monitores fazem com que
a programao paralela seja muito menos sujeita a erros do que com semforos. Entretanto,
monitores possuem suas desvantagens. Como j foi dito, monitores so um conceito da
linguagem de programao. O compilador deve reconhec-los e arranjar a excluso mtua de
acordo. C, Pascal e outras linguagens no possuem monitores, portanto no se pode esperar que
os compiladores dessas linguagens dem algum suporte a excluso mtua. De fato, como
poderia o compilador saber quais procedimentos esto em monitores e quais no esto?
Estas mesmas linguagens no possuem semforos, mas adicion-los a elas fcil:
basta escrever algumas rotinas para as operaes P e V e adicionar estas rotinas s bibliotecas
de funes. Os compiladores nem precisam saber do fato que os semforos existem. claro
que o sistema operacional precisa suportar semforos, para que as operaes P e V possam ser
implementadas.
Para utilizar monitores, necessria uma linguagem que os tenha por natureza.
Muito poucas linguagens, como Concurrent Euclid os possuem, e compiladores para elas so
raros.
Outro problema com monitores, e tambm com semforos, que eles foram
projetados para sistemas monoprocessados, ou para sistemas multiprocessados com memria
compartilhada. Em sistemas distribudos, onde cada CPU possui sua prpria memria e est
conectada s outras atravs de um rede de computadores, semforos e monitores no podem ser

aplicados.

2.3.9Passagem de Mensagens
(ver notas de aula e texto em ingls do Silberschatz na pgina)

2.4Deadlocks e Adiamento Indefinido


Um processo em um sistema multiprogramado dito estar em uma situao de
deadlock quando ele est esperando por um evento particular que jamais ocorrer. Em um
deadlock em um sistema, um ou mais processos esto em deadlock.
Em sistemas multiprogramados, o compartilhamento de recursos uma das
principais metas do sistemas operacionais. Quando recursos so compartilhados entre uma
populao de usurios, e cada usurio mantm controle exclusivo sobre os recursos particulares
a ele alocados, possvel que haja a ocorrncia de deadlocks no sentido em que alguns usurios
jamais sejam capazes de terminar seu processamento.
O estudo de deadlocks envolve quatro reas: prevenir, evitar, detectar e recuperar.
Tambm relacionados com deadlocks esto os conceitos de adiamento indefinido e starvation.

2.4.1Exemplos de Deadlocks
Deadlocks podem desenvolver-se de vrias maneiras. Se um processo recebe a
tarefa de esperar pela ocorrncia de um determinado evento, e o sistema no inclui proviso
para sinalizar aquele evento, ento temos um deadlock de um processo. Deadlocks desta
natureza so extremamente difceis de detectar, pois esto intimamente associados ao cdigo do
processo, provavelmente com erros, neste caso.
A maioria dos deadlocks em sistemas reais geralmente envolve mltiplos processos
competindo por mltiplos recursos. Vejamos alguns exemplos comuns.

2.4.2Um Deadlock de Trfego


A figura 2.6 ilustra um tipo de deadlock que ocasionalmente se desenvolve em

cidades. Um certo nmero de automveis esto tentando atravessar uma parte da cidade
bastante movimentada, mas o trfego ficou completamente paralisado. O trfego chegou numa
situao onde somente a polcia pode resolver a questo, fazendo com que alguns carros recuem
na rea congestionada. Eventualmente o trfego volta a fluir normalmente, mas a essa altura os
motoristas j se aborreceram e perderam tempo considervel.

Figura 2.6 - Um deadlock de trfego

2.4.3Um Deadlock Simples de Recursos


Muitos deadlocks ocorrem em sistemas de computao devido natureza de
recursos dedicados (isto , os recursos somente podem ser usados por um usurio por vez,
algumas vezes sendo chamados de recursos serialmente reusveis).
Suponha que em um sistema o processo A detm um recurso 1, e preciso alocar o
recurso 2 para poder prosseguir. O processo B, por sua vez, detm o recurso 2, e precisa do
recurso 1 para poder prosseguir. Nesta situao, temos um deadlock, porque um processo est
esperando pelo outro. Esta situao de espera mtua chamada muitas vezes de espera circular
(circular wait).

2.4.4Deadlock em Sistemas de Spooling


Sistemas de spooling costumam estar sujeitos a deadlocks. Um sistema de spooling
serve, por exemplo, para agilizar as tarefas de impresso do sistema. Ao invs do aplicativo
mandar linhas para impresso diretamente para a impressora, ele as manda para o spool, que se
encarregar de envi-las para a impressora. Assim o aplicativo rapidamente liberado da tarefa

de imprimir. Vrios jobs de impresso podem ser enfileirados e sero gerenciados pelo sistema
de spooling.
Em alguns sistemas de spool, todo o job de impresso deve ser gerado antes do
incio da impresso. Isto pode gerar uma situao de deadlock, uma vez que o espao disponvel
em disco para a rea de spooling limitado. Se vrios processos comearem a gerar seus dados
para o spool, possvel que o espao disponvel para o spool fique cheio antes mesmo de um
dos jobs de impresso tiver terminado de ser gerado. Neste caso, todos os processos ficaro
esperando pela liberao de espao em disco, o que jamais vai acontecer, e portanto gerando
uma situao de deadlock. A soluo neste caso seria o operador do sistema cancelar um dos
jobs parcialmente gerados.
Para resolver o problema sem a interveno do operador, o SO poderia alocar uma
rea maior de spooling, ou a rea de spooling poderia ser varivel dinamicamente. Alguns
sistemas, como o do Windows 3.x/95, utilizam todo o espao em disco disponvel Entretanto,
pode acontecer de o disco possuir pouco espao e o problema ocorrer da mesma forma.
A soluo definitiva seria implementar um sistema de spooling que comeasse a
imprimir assim que algum dado estivesse disponvel, sem a necessidade de se esperar por todo o
job. Isso faria com que o espao fosse sendo liberado gradualmente, na velocidade em que a
impressora conseguisse consumir os dados. Este um problema tpico de uma relao produtorconsumidor.
Nos sistemas operacionais mais populares, como o Windows 95, o sistema de spool
pode ser configurado para comear a imprimir assim que uma pgina estiver disponvel em
disco (isto porque algumas impressoras so orientadas a pgina, como as impressoras laser). No
Windows 3.x, o spool s iniciava a impresso aps todo o job de impresso ter sido gerado.

2.4.5Adiamento Indefinido
Em sistemas onde processos ficam esperando pela alocao de recursos ou pelas
decises de escalonamento, possvel que ocorra adiamento indefinido tambm chamado de
bloqueamento indefinido ou starvation).
Adiamento indefinido pode ocorrer devido s polticas de escalonamento de
recursos do sistema. Quando recursos so alocados segundo um esquema de prioridades,
possvel que um determinado processo espere indefinidamente por um recurso conforme
processos com prioridades mais altas venham chegando. Os sistemas operacionais devem ser
justos com processos em espera, bem como devem considerar a eficincia de todo o sistema.

Em alguns sistemas, o adiamento indefinido pode ser evitado permitindo que a prioridade de
um processo em espera cresa conforme ele espera por um recurso. Isto chamado de aging
(envelhecimento).

2.4.6Conceitos de Recursos
Um sistema operacional pode ser visto de forma mais ampla como um gerenciador
de recursos. Ele responsvel pela alocao de vrios recursos de diversos tipos. A riqueza dos
tipos de recursos que faz o assunto Sistemas Operacionais ser interessante de ser estudado.
Alguns recursos so preemptveis. O maior exemplo a CPU. Memria tambm
pode ser preemptvel (veremos memria virtual).
Certos recursos so no-preemptveis, e no podem ser tomados de processos aos
quais foram alocados. Ex. unidades de fita. Contra-ex. disco.
Alguns recursos so compartilhados entre vrios processos. Unidades de disco so
compartilhadas em geral. Memria principal e CPU so compartilhadas; apesar de que em um
instante a CPU pertence a um nico processo, mas sua multiplexao entre os vrios processos
transmite a idia de que est sendo compartilhada.
Dados e programas so certamente os recursos que mais precisam ser controlados e
alocados. Em sistemas multiprogramados, vrios usurios podem querer simultaneamente usar
um programa editor. Seria desperdcio de memria ter-se uma cpia do editor para cada
programa executando. Ao contrrio, uma nica cpia do cdigo trazida para a memria e
vrias cpias dos dados so feitas, uma para cada usurio. Uma vez que o cdigo est em uso
por vrios usurios simultaneamente, ele no pode mudar. Cdigo que no pode ser mudado
enquanto est em uso dito reentrante. Cdigo que pode ser mudado mas que reinicializada
cada vez que usado dito serialmente reusvel. Cdigo reentrante pode ser compartilhado
entre vrios processos, enquanto cdigo serialmente reusvel s pode ser alocado a um processo
por vez.
Quando chamamos recursos compartilhados particulares, devemos ser cuidadosos
para determinar se eles podem ser usados por vrios processos simultaneamente, ou se podem
ser usados por vrios processos, mas um de cada vez. Estes ltimos so os recursos que tendem
estar envolvidos em deadlocks.
Um sistema possui um nmero finito de recursos para serem distribudos entre
processos concorrentes. Os recursos so classificados segundo vrios tipos, sendo que cada tipo

pode consistir de uma quantidade de instncias idnticas. Por exemplo, se considerarmos o tipo
de recurso CPU, em uma mquina com dois processadores, temos duas instncias do recurso
CPU.
Se um processo requisita uma instncia de um tipo de recurso, a alocao de
qualquer instncia daquele tipo ir satisfazer a requisio. Se em um determinado sistema esta
satisfao no ocorrer, isto significa que as instncias no so idnticas, e que as classes de tipos
de recursos no esto definidas corretamente. Como exemplo (Silberschatz, 1994), suponha que
um sistema possui duas impressoras. Elas poderiam ser definidas como instncias de um mesmo
tipo de recurso. Entretanto se uma estivesse instalada no andar trreo do prdio, e a outra no 9
andar, os usurios do andar trreo podem no enxergar as duas impressoras como sendo
equivalentes. Neste caso, classes de recursos separadas precisariam ser definidas para cada
impressora.
Um processo pode requisitar um recurso antes de us-lo, e deve liber-lo depois de
seu uso. Um processo pode requisitar quantos recursos precisar para desempenhar a tarefa para
a qual foi projetado. Obviamente, o nmero de recursos requisitados no pode exceder o
nmero total de recursos disponveis no sistema. Em outras palavras, o processo no pode
requisitar trs impressoras se o sistema somente possui duas.
Em uma situao de operao normal, um processo pode utilizar um recurso
somente nesta seqncia:
1. Requisitar: se a requisio no pode ser atendida imediatamente (por exemplo, o
recurso est em uso por outro processo), ento o processo requisitante deve esperar
at obter o recurso;
2. Usar: O processo pode operar sobre o recurso (por exemplo, se o recurso uma
impressora, ele pode imprimir);
3. Liberar: O processo libera o recurso.

2.4.7Quatro Condies Necessrias para Deadlock


Coffman, Elphick, e Shosani (1971) enumeraram as seguintes quatro condies
necessrias que devem estar em efeito para que um deadlock exista.
Processos requisitam controle exclusivo dos recursos que eles necessitam (condio
mutual exclusion);
Processos detm para si recursos j alocados enquanto esto esperando pela alocao

de recursos adicionais (condio hold and wait, ou wait for);


Recursos no podem ser removidos dos processos que os detm at que os recursos
sejam utilizados por completo (condio no preemption);
Uma cadeia circular de processos existe de forma que cada processo detm um ou mais
recursos que esto sendo requisitados pelo prximo processo na cadeia (condio
circular wait).

Como todas as condies so necessrias para um deadlock existir, a existncia de


um deadlock implica que cada uma dessas condies estejam em efeito. Como veremos adiante,
isto nos ajudar a desenvolver esquemas para prevenir deadlocks.

2.4.8Mtodos para Lidar com Deadlocks


Basicamente, h trs maneiras diferentes de lidar com deadlocks:
Pode ser usado um protocolo para garantir que em um determinado sistema deadlocks
jamais ocorrero;
Pode-se deixar o sistema entrar em um estado de deadlock e ento tratar da sua
recuperao;
Pode-se simplesmente ignorar o problema, e fingir que deadlocks nunca ocorrem. Esta
soluo usada pela maioria dos sistemas operacionais, inclusive o UNIX.

Para garantir que deadlocks nunca ocorrem, o sistema pode tanto usar um esquema
de prevenir deadlocks, ou evitar deadlocks. A preveno de deadlocks um conjunto de
regras de requisio de recursos que garantem que pelo menos uma das condies necessrias
para a ocorrncia de deadlocks no esteja em efeito. Evitar deadlocks, por outro lado, requer
que seja fornecida ao sistema operacional informao adicional sobre quais recursos um
processo ir requisitar e usar durante sua execuo. Com o conhecimento dessa informao,
possvel decidir, a cada requisio, se o processo pode prosseguir ou se deve esperar. Cada
requisio requer que o sistema operacional considere os recursos atualmente disponveis, os
recursos alocados a cada processo, e as futuras requisies e liberaes de cada processo, para
que possa decidir se a requisio corrente pode ser satisfeita ou deve ser adiada.
Se no so usadas estratgias de preveno ou para evitar deadlocks, existe a
possibilidade de ocorrncia destes. Neste ambiente, o sistema operacional pode possuir um

algoritmo que consiga determinar se ocorreu um deadlock no sistema, alm de um algoritmo


que faa a recuperao da situao de deadlock.
Se um sistema que nem previne, evita, ou recupera situaes de deadlock, se um
deadlock ocorrer, no haver maneira de saber o que aconteceu exatamente. Neste caso, o
deadlock no detectado causar a deteriorao do desempenho do sistema, porque recursos
esto detidos por processos que no podem continuar, e porque mais e mais processos,
conforme requisitam recursos, entram em deadlock. Eventualmente o sistema ir parar de
funcionar, e ter que ser reinicializado manualmente.
Apesar do mtodo de ignorar os deadlocks no parecer uma abordagem vivel para
o problema da ocorrncia de deadlocks, ele utilizado em vrios sistemas operacionais. Em
muitos sistemas, deadlocks ocorrem de forma no freqente, como por exemplo, uma vez por
ano. Assim, muito mais simples e barato usar este mtodo do que os dispendiosos mtodos
de prevenir, evitar, detectar e recuperar de situaes de deadlock. Alm disso, podem existir
situaes em que um sistema fica aparentemente congelado sem estar, no entanto, em
situao de deadlock. Imagine, por exemplo, um sistema rodando um processo em tempo real
com a mxima prioridade, ou ainda, um processo rodando em um sistema com escalonador no
preemptivo.

2.4.9Preveno de Deadlocks
Como vimos, para que um deadlock ocorra, todas as condies necessrias para
ocorrncia de deadlocks, que listamos anteriormente, devem estar em efeito. Isto quer dizer que
se garantirmos que somente uma delas no possa ocorrer, estaremos prevenindo a ocorrncia
de deadlocks em um determinado sistema. Examinemos as quatro condies separadamente:

2.4.9.1Negando a Condio Mutual Exclusion


Conforme afirmamos acima, a condio mutual exclusion no deve ser negada,
pois dois processos acessando um recurso simultaneamente poderiam levar o sistema a uma
situao de caos. Imagine o exemplo de dois processos acessando uma mesma impressora ao
mesmo tempo! Uma soluo utilizar um sistema de spool, onde um nico processo de spool
acessa a impressora diretamente, e no acessa nenhum outro recurso. Uma vez que os processos
no imprimem diretamente, e o processo de spool acessa somente o recurso impressora,
deadlocks no podem ocorrer.

O problema que nem todos os recursos podem ser alocados via spooling. Alm
disso, o prprio sistema de spooling pode levar a situaes de deadlock, conforme j
discutimos.

2.4.9.2Negando a Condio Hold and Wait


A primeira estratgia de Havender requer que todos os recursos que um processo
precise devem ser requisitados de uma s vez. O sistema deve liberar os recursos segundo uma
poltica tudo ou nada. Se todos os recursos que o processo requisitou esto disponveis, ento
o sistema pode aloc-los todos de uma vez ao processo, que poder prosseguir. Se, por outro
lado, nem todos os recursos requisitados esto disponveis, ento o processo deve esperar at
que todos eles estejam disponveis. Enquanto o processo espera, entretanto, ele no deve deter
nenhum recurso. Assim a condio hold and wait negada e deadlocks simplesmente no
podem ocorrer.
Esta soluo parece ser boa mas pode levar a um srio desperdcio de recursos. Por
exemplo, suponha um programa que l dados de uma unidade de fita, processa-os por uma hora,
e em seguida imprime alguns grficos em um plotter. Uma vez que ambas a unidade de fita e o
plotter estejam disponveis, o programa pode prosseguir. O desperdcio ocorre porque o plotter
ficar alocado ao processo durante uma hora antes de ser efetivamente utilizado.
Outro problema a possibilidade de um processo requisitando todos os seus
recursos de uma s vez ficar indefinidamente esperando, se outros processos estiverem usando
os recursos que ele deseja com bastante freqncia.
De qualquer forma, esta abordagem evita deadlocks.

2.4.9.3Negando a Condio No Preemption


Negar a condio de no preempo uma estratgia ainda pior do que a anterior.
Para vrios recursos, como uma impressora, no interessante que um processo os perca
durante seu uso.

2.4.9.4Negando a Condio Circular Wait


A condio circular wait pode ser eliminada de vrias formas. Uma maneira
simplesmente estabelecer uma regra que diga que um processo s pode alocar um nico recurso

em um dado momento. Se ele precisa de um segundo recurso, deve liberar o primeiro. Para um
processo que necessita copiar um arquivo bastante grande para uma impressora (o processo de
spooling, por exemplo), isto inaceitvel.
Uma estratgia melhor seria utilizar a terceira estratgia de Havender, que
determina que todos os recursos devem ser numerados em ordem crescente. Assim, processos
podem requisitar recursos sempre que quiserem, mas todas as requisies devem ser em ordem
crescente de numerao. Tomando a figura 10.3 como exemplo, um processo poderia requisitar
o recurso R1 e em seguida o recurso R3, mas no o inverso. O grafo de alocao mostrado na
figura 2.7 jamais possuir ciclos, evitando assim a condio circular wait.

R10
P3
R9
P2
R8
P1
P2

R7
P1
R6

R5

P1

R4
P1
P2

R3

R2

R1

Figura 2.7 - Ordenao Linear para Preveno de Deadlocks

3GERENCIAMENTO DE MEMRIA
Memria um importante recurso que deve ser cuidadosamente gerenciado. Apesar
de um computador domstico atual possuir dezenas ou at mesmo centenas de vezes mais
memria que um computador IBM 7094 (o maior computador existente no incio dos anos 60),
o tamanho dos programas de computador tem crescido em uma escala to grande quanto da
quantidade de memria dos computadores.
A memria sempre foi vista como um recurso caro e por isso merece cuidados para
o seu gerenciamento correto. Apesar da queda vertiginosa do preo da memria real, esta ainda
muitas vezes mais cara do que a memria secundria (discos, fitas,etc.).
O componente do sistema operacional responsvel pela administrao da memria
chamado de gerenciador de memria. Seu papel consiste em saber quais partes da memria
esto ou no em uso, alocar memria para os processos quando dela necessitam e desalocar
quando deixam de us-la ou terminam, e gerenciar as trocas entre a memria principal e o disco
quando a memria principal no grande o suficiente para conter todos os processos.
Este captulo visa abordar alguns esquemas de gerenciamento de memria, desde
alguns simples at os mais complexos. Sistemas de gerenciamento de memria podem ser
divididos em dois grupos: aqueles que movem processos entre memria e disco durante sua
execuo (paginao e swapping), e aqueles que no o fazem. Cada abordagem possui
vantagens e desvantagens. A escolha do melhor esquema de gerenciamento de memria
depende de vrios fatores, especialmente do projeto do hardware do sistema. Como veremos
mais adiante, vrios algoritmos para gerenciamento de memria requerem algum suporte do
hardware.

3.1Conceitos Bsicos
Como vimos no incio do curso, memria um componente essencial para a
operao de sistemas de computao modernos. A memria um grande vetor de palavras ou
bytes (o tamanho de um palavra depende de cada mquina), cada qual com seu prprio
endereo. A CPU busca instrues do programa em memria de acordo com o valor do
registrador contador de programas (program counter, que no caso dos microprocesadores Intel

x86, chamado de IP Instruction Pointer, ou seja, ponteiro de instrues). Estas instrues


podem causar a busca ou o armazenamento adicionais para endereos especficos de memria.
Tipicamente, um ciclo de execuo de uma instruo de processador primeiramente
carregar uma instruo da memria para o processador. A instruo ser decodificada e pode
fazer com que operandos sejam carregados da memria. Aps a execuo da instruo sobre os
operandos (por exemplo, uma soma), resultados eventualmente podem ser armazenados de
volta na memria. Vale observar que a unidade de memria da mquina apenas enxerga uma
seqncia de endereos de memria; ela no sabe como esses endereos so gerados (se o
contador de instrues, se uma referncia a operandos, etc.), ou o qu so seus contedos (se
so instrues ou dados). Assim, nossa preocupao no saber como um programa determina
quais endereos de memria ele precisa acessar, mas sim, em saber qual a seqncia de
endereos que o programa executando deseja acessar.

3.1.1Ligao de Endereos (Address Binding)


Normalmente, um programa reside em um disco como um arquivo binrio
executvel. O programa deve ser trazido para a memria e introduzido no sistema como um
processo para que possa ser executado. Dependendo do sistema de gerenciamento de memria
em uso, o processo pode ser movido entre disco e memria durante sua execuo. Uma coleo
de processos em disco que esto esperando para serem trazidos para memria para execuo,
formam uma fila de entrada.

O procedimento normal selecionar um dos processos da fila de entrada e carreglo na memria. Conforme o processo executa, ele acesa instrues e dados da memria.
Eventualmente o processo termina, e seu espao de memria declarado como disponvel.

Programa
fonte

Co mpilador ou
assembler

Tempo de
compilaao

Mdulo
objeto
Outros
mdulos
objeto
Link editor
(ligador)

Biblioteca
de sistema

Mdulo
carregvel

Tempo de
carregamento

Carregador
(loader)
Biblioteca de
sistema
carregada
dinamicamente

Imagem em
mem ria do
programa
binrio

Tempo de
execuo

Figura 3.1 Passos no processamento de um programa de usurio


Muitos sistemas permitem que um processo de um usurio resida em qualquer parte
da memria fsica. Dessa forma, apesar do espao de endereamento do computador comear
em 00000, por exemplo, o primeiro endereo do processo do usurio no precisa ser 00000.
Este arranjo afeta que o programa do usurio pode utilizar. Na maioria dos casos, um programa

de usurio passar por vrias etapas antes de ser executado, conforme a figura 3.1. Endereos
podem ser representados de diferentes formas nestes passos. Endereos no programa fonte
normalmente so simblicos (por exemplo, a varivel cont). Um compilador ir tipicamente
ligar esses endereos simblicos a endereos relocveis (como por exemplo, 14 bytes a
partir do incio do bloco desse programa). O link editor ou carregador (loader) por sua vez
ligar esses endereos relocveis a endereos absolutos (tal como 74014). Cada uma das
ligaes um mapeamento de um espao de endereamento para outro.
Classicamente, a ligao de instrues e dados para endereos de memria pode ser
feita em qualquer um dos passos citados:

Tempo de compilao: se, em tempo de compilao, possvel saber onde o


programa residir em memria, ento cdigo absoluto pode ser gerado. Por
exemplo, se sabido a priori que um processo de usurio reside comeando na
localizao R, ento o cdigo gerado pelo compilador ir iniciar naquela
localizao e continuar a partir dali. Se, mais tarde, a localizao de incio
mudar, ento ser necessrio recompilar este cdigo. Os programas em formato
.COM do MS-DOS so cdigos ligados absolutamente a endereos de memria
em tempo de compilao.

Tempo de carregamento: se, em tempo de compilao, no sabido onde o


processo residir em memria, ento o compilador deve gerar cdigo relocvel.
Neste caso, a ligao final a endereos de memria adiada at o momento de
carga do programa. Se o endereo de incio mudar, ser somente necessrio
recarregar o cdigo para refletir a mudana do endereo inicial.

Tempo de execuo: se o processo pode ser movido durante sua execuo de


um segmento para outro, ento a ligao a endereos de memria deve ser
adiada at o momento da execuo do programa. Para este esquema funcionar,
necessrio que o hardware suporte algumas caractersticas, conforme veremos
mais adiante.

3.1.2Carregamento Dinmico (Dynamic Loading)


Para atingir melhor utilizao do espao em memria, pode-se usar carregamento
dinmico. Com carregamento dinmico, uma rotima no carregada em memria at que seja
chamada. Todas as rotinas so mantidas em disco em um formato relocvel. O programa
principal carregado em memria e executado. Quando uma rotina precisa chamar outra rotina,

a rotina chamadora primeiramente verifica se a rotina a ser chamada j est carregada. Se no


est, o carregador-ligador relocvel chamado para carregar a rotina desejada em memria, e
para atualizar as tabelas de endereos do programa para refletir esta mudana. Em seguida, o
controle passado para a rotina recm carregada.
A vantagem do carregamento dinmico que uma rotina no usada jamais
carregada em memria. Este esquema particularmente til quando grandes quantidades de
cdigo so necessrias para manipular casos que ocorrem raramente, como rotinas de
tratamento de erros, por exemplo. Neste caso, apesar do tamanho total do programa ser grande,
a poro efetivamente usada (e portanto carregada) pode ser muito menor.
Carregamento dinmico no requer suporte especial do sistema operacional.
responsabilidade dos usurios projetar seus programas para tomar vantagem deste esquema.
Sistemas operacionais, entretanto, podem ajudar o programador provendo rotinas de biblioteca
que implementam carregamento dinmico.
Sem carregamento dinmico, seria impossvel a uma aplicao atual razoavelmente
pesada, como o Microsoft Word, ser carregado rapidamente. H algumas verses, quando o
Microsoft Word invocado, uma rotina principal de tamanho pequeno rapidamente carregada,
mostrando uma mensagem do aplicativo para o usurio, enquanto as outras rotinas usadas
inicialmente terminam de ser carregadas.

3.1.3Ligao Dinmica
A figura 3.1 tambm ilustra bibliotecas ligadas dinamicamente. Muitos sistemas
operacionais suportam somente ligaes estticas de bibliotecas de funes, na qual as
bibliotecas de sistema so tratadas como qualquer outro mdulo objeto e so combinadas pelo
carregador dentro da imagem binria do programa em memria. O conceito de ligao dinmica
similar ao de carregamento dinmico. Ao invs da carga de rotinas ser adiada at o momento
da execuo do programa, a ligao de rotinas adiada at o tempo de execuo. Esta
caracterstica normalmente usada com bibliotecas de sistema, tais como bibliotecas de
subrotinas da linguagem em uso, como por exemplo, a biblioteca stdio da linguagem C. Sem
essa facilidade, todos os programas em um sistema precisam possuir sua prpria cpia da
biblioteca bsica (ou pelo menos das funes referenciadas pelo programa) includa na imagem
executvel. Este esquema desperdia ambos espao em disco e espao em memria principal.
Com ligao dinmica, um stub includo na imagem para cada referncia a uma rotina de
biblioteca. Este stub um pequeno cdigo que indica como localizar a rotina de biblioteca

apropriada residente em memria, ou como carregar a biblioteca se a rotina ainda no est


presente em memria.
Quando este stub executado, ele verifica se a rotina desejada j est em memria.
Se a rotina no est em memria, o programa a carrega. De qualquer forma, o stub substitui a si
mesmo pelo endereo da rotina, e em seguida a executa. Assim, da prxima vez que o trecho de
cdigo que referencia a rotina atingido, a rotina de biblioteca executada diretamente, sem
custo novamente da ligao dinmica. Sob este esquema, todos os processos que usam uma
mesma biblioteca de linguagem executam somente sobre uma cpia do cdigo da biblioteca.
Este recurso pode ser til tambm para atualizaes de verses de bibliotecas, como
o conserto de bugs. Uma biblioteca pode ser substituda pela nova verso, e todos os programas
que a referenciam usaro a nova verso. Sem ligao dinmica, todos os programas que
usassem tais bibliotecas precisariam ser religados para funcionarem com a nova biblioteca. Para
que programas no executem acidentalmente verses mais recentes e incompatveis de
bibliotecas, uma informao sobre verso da biblioteca includa tanto no programa quanto na
biblioteca. Mais do que uma verso de biblioteca podem estar presentes em memria, e cada
programa usa a sua informao de verso para decidir qual biblioteca usar. Pequenas mudanas
normalmente mantm o nmero de verso, enquanto mudanas mais radicais incrementam o
nmero de verso. Este esquema tambm chamado de bibliotecas compartilhadas.
Ligao dinmica precisa da ajuda do sistema operacional para funcionar. Se os
processos em memria so protegidos uns dos outros, como veremos adiante, ento o sistema
operacional a nica entidade que pode verificar se a rotina necessria est no espao de
memria de outro processo, e pode permitir que mltiplos processos acessem os mesmos
endereos de memria. Este conceito ser expandido quando discutirmos paginao.
Analisando o funcionamento de bibliotecas dinmicas, vemos que elas utilizam-se
de cdigo reentrante para que vrios processos compartilhem uma nica cpia da biblioteca em
memria. Para exemplificar com um sistema operacional conhecido, todos os arquivos .DLL do
Microsoft Windows so bibliotecas de ligao dinmica.

3.1.4Overlays
Em algumas situaes pode ser que a memria fsica no seja suficiente para conter
todo o programa do usurio. Uma forma de resolver esse problema o uso de overlays. As
sees do programa no necessrias em um determinado momento podem ser substitudas por
uma outra poro de cdigo trazida do disco para execuo, conforme ilustra a figura 3.2. O

overlay manual requer planejamento cuidadoso e demorado. Um programa com uma estrutura
de overlays sofisticada pode ser difcil de modificar. Alguns compiladores (Turbo Pascal)
podem gerenciar overlays automaticamente, mas sem eficincia muito grande. Como veremos
adiante, os sistemas de memria virtual eliminaram o trabalho do programador com a definio
de overlays.
c

fase de
inicializao

rea de
Overlay
Poro mnima
do programa do
usurio que deve
permanecer em
memria at o
final da execuo
Sistema
Operacional

fase de
processamento

fase de
gerao
de
resultado

b
b
b

Figura 3.2 - Uma estrutura de overlay tpica

3.2Endereamento Lgico e Endereamento Fsico


Um endereo gerado pela CPU normalmente referido como sendo um endereo
lgico, enquanto que um endereo visto pela unidade de memria do computador (isto , aquele
carregado no registrador de endereo de memria do controlador de memria) normalmente
referido como sendo um endereo fsico.
Os esquemas de ligao de endereos em tempo de compilao e em tempo de
carregamento resultam em um ambiente onde os endereos lgicos e fsicos so os mesmos.
Entretanto, a ligao de endereos em tempo de execuo faz com que endereos lgicos e
fsicos sejam diferentes. Neste caso, nos referimos normalmente ao endereo lgico como um
endereo virtual. Os termos endereo lgico e endereo virtual so, na verdade, a mesma coisa.
O conjunto de todos os endereos lgicos gerados por um programa chamado de espao de
endereos lgico; o conjunto dos endereos fsicos correspondentes a estes endereos lgicos
chamado de espao de endereos fsico. Assim, no esquema e ligao de endereos em tempo
de execuo, os espaos de endereos lgico e fsico diferem.
O mapeamento em tempo de execuo de endereos virtuais para endereos fsicos

feito pela unidade de gerenciamento de memria (MMU Memory Management Unit), que
um dispositivo de hardware. Existem diversas maneiras de fazer este mapeamento, conforme
discutiremos mais adiante. Vejamos um esquema de MMU simples (figura 3.3).

Registrador de
relocao
Endereo
lgico
CPU

346

14000
+

Endereo
fsico
14346

Memria

MMU

Figura 3.3 Relocao dinmica usando um registrador de relocao

Conforme ilustrado na figura, este esquema requer um suporte do hardware,


particularmente, na MMU. Um registrador de relocao mantm um valor que deve ser somado
a qualquer endereo requisitado memria, gerados por um processo de usurio em execuo.
Conforme o exemplo, se o endereo base para o processo 14000, ento uma tentativa do
processo do usurio acessar o endereo de memria 0 dinamicamente relocada para o
endereo fsico 14000, enquanto uma tentativa de acesso ao endereo lgico (virtual) 346
mapeado para o endereo fsico 14346. O sistema operacional MS-DOS, quando executado em
um processador Intel 80x86 (uma vez que existem emuladores de MS-DOS para outras
mquinas), utiliza quatro registradores de relocao enquanto carrega e executa processos.
Vale observar que o programa do usurio nunca enxerga os reais endereos fsicos
de memria. O programa em C, por exemplo, pode criar um ponteiro para o endereo 346,
armazen-lo em memria, manipul-lo, compar-lo com outros endereos sempre como o
endereo 346. Somente quando este valor usado como um endereo de memria, que ele
ser mapeado com relao ao endereo base de memria. O programa do usurio lida com
endereos lgicos. O hardware de mapeamento de memria converte endereos lgicos em
endereos fsicos. Isto forma a ligao de endereos em tempo de execuo que discutimos nos
itens anteriores. O localizao final de uma referncia a um endereo de memria no

determinada at que a referncia seja efetivamente feita.

3.3Swapping
Um processo precisa estar em memria para executar. Um processo, entretanto,
pode ser temporariamente ser retirado (swapped) da memria para uma rea de armazenamento
de trocas (rea de swapping), de forma que mais tarde seja trazido de volta para a memria para
que continue executando. Por exemplo, suponha um ambiente multiprogramado com um
algoritmo de escalonamento de CPU round-robin. Quanto o quantum de determinado processo
expira, o gerenciador de memria do SO comear a retirar (swap out) o processo recm
interrompido, e recolocar (swap in) outro processo no espao de memria que foi liberado.
Enquanto isso, o escalonador de CPU ir alocar uma fatia de tempo para outro processo em
memria. Conforme cada processo tem seu quantum expirado, ele ser trocado (swapped) por
outro processo que estava na rea de swapping. Em uma situao ideal, o gerenciador de
memria conseguir trocar processos em uma velocidade tal que sempre haja processos em
memria, prontos para executar, sempre que o escalonador de CPU decidir colocar outro
processo em execuo. O quantum dos processos devem tambm ser suficientemente grande
para que os processos consigam processar por um tempo razovel antes de serem retirados
(swapped out) da memria.
Uma variao desta poltica de swapping poderia ser usada para algoritmos de
escalonamento baseados em prioridades. Se um processo com maior prioridade chega no
sistema e deseja CPU, ento o gerenciador de memria poderia retirar um ou mais processos
com prioridades mais baixas de forma que ele possa carregar e executar o processo de
prioridade mais alta. Quando este processo de alta prioridade terminasse, os processos de baixa
prioridade poderiam ser trazidos de volta para a memria e continuarem executando. Esta
variante de swapping s vezes chamada de roll out, roll in.
Normalmente, um processo que foi retirado da memria ser trazido de volta no
mesmo espao de memria que ocupava anteriormente. Esta restrio pode existir ou no
conforme o mtodo de ligao de endereos de memria. Se a ligao de endereos de memria
feita em tempo de compilao ou de carregamento, ento o processo no pode ser movido
para localizaes diferentes de memria. Se a ligao em tempo de execuo usada, ento
possvel retirar um processo da memria e recoloc-lo em um espao de memria diferente,
uma vez que os endereos fsicos so calculados em tempo de execuo.

A tcnica de swapping requer uma rea de armazenamento. Normalmente, este


espao para armazenamento um disco (ou uma partio de um disco) de alta velocidade. Ele
deve ser grande o suficiente para acomodar cpias de todas as imagens de memria para todos
os usurios, e deve prover acesso direto a essas imagens de memria. O sistema mantm uma
fila de pronto (ready queue) consistindo de todos os processos cujas imagens de memria esto
na rea de armazenamento ou em memria real, e que esto prontos para executar. Toda vez que
o escalonador de CPU decide executar um processo, ele chama o despachador (dispatcher). O
despachador verifica se o prximo processo da fila est ou no em memria. Se o processo no
est, e no h uma rea de memria livre para carreg-lo, o despachador retira (swap out) um
processo atualmente em memria e recoloca (swap in) o processo desejado. Ele ento restaura o
contexto do processo normalmente (contedos de registradores, etc.), muda seu estado para
running, e transfere o controle para o processo.
claro que o tempo de troca de contexto no caso de um sistema com swapping
razoavelmente alto. Para se ter uma idia do tempo da troca de contexto, suponhamos que um
processo de usurio tenha tamanho de 100KB e que o dispositivo de armazenamento de
swapping um disco rgido padro com taxa de transferncia de 1 MB por segundo. A
transferncia real dos 100KB do processo de ou para memria leva:
100 KB / 1000 KB por segundo

= 1/10 segundo
= 100 milisegundos

Assumindo que no haja tempo de posicionamento dos cabeotes do disco rgido, e


um tempo mdio de latncia (tempo at o disco girar para a posio desejada) de 8
milisegundos, o tempo de swap leva 108 milisegundos. Como necessrio a retirada de um
processo a recolocao de outro, este tempo fica em torno de 216 milisegundos.
Para o uso eficiente de CPU, desejvel que o tempo de execuo para cada
processo seja longo em relao ao tempo de swap. Dessa forma, em um algoritmo de
escalonamento round-robin, por exemplo, o tempo do quantum deveria ser substancialmente
maior do que 0.216 segundos.
Note que a maior parte do tempo de swap o tempo de transferncia. O tempo de
transferncia diretamente proporcional quantidade de memria trocada (swapped). Se um
determinado sistema de computao tiver 1 MB de memria principal e um sistema operacional
residente de 100 KB, o tamanho mximo para um processo de usurio de 900 KB. Entretanto,
muitos processos de usurios podem ser muito menores que este tamanho, por exemplo 100 KB
cada. Um processo de 100 KB poderia ser retirado da memria em 108 milisegundos, ao
contrrio dos 908 milisegundos necessrios para um processo de 900 KB. Portanto, seria til

saber exatamente quanta memria um processo de usurio est usando, no simplesmente


quanto ele poderia estar usando. Assim, precisaramos apenas retirar da memria a quantidade
de memria realmente usada, reduzindo o tempo de swap. Para que este esquema seja efetivo, o
usurio deve manter o sistema informado de quaisquer mudanas das necessidades de memria.
Dessa forma, um processo com necessidades dinmicas de memria dever fazer chamadas de
sistema (solicita_memria e libera_memria) para informar o sistema operacional de suas
mudanas de necessidades por memria.
H outras limitaes com o swapping. Se desejamos retirar um processo da
memria, devemos ter certeza de que ele est completamente ocioso. Uma preocupao em
especial quanto a solicitaes de I/O pendentes. Se um processo est esperando por uma
operao de I/O, poderamos querer troc-lo para a rea de swapping para liberar a memria
que est ocupando. Entretanto, se a operao de I/O est acessando o espao de memria do
usurio de forma assncrono, como buffers de I/O, ento o processo no pode ser retirado da
memria.
Como exemplo, assuma que a operao de I/O do processo P1 foi enfileirada
porque o dispositivo estava ocupado. Se trocarmos o proccesso P1 pelo processo P2 que estava
na rea de swapping, assim que o dispositivo tornar-se livre, a operao de I/O poder tentar
usar uma rea de memria que agora pertence ao processo P2. Duas solues possveis so: (1)
nunca retirar para a rea de swap um processo com I/O pendente; ou (2) executar operaes de
I/O somente em buffers do prprio sistema operacional. Neste ltimo caso, as transferncias
entre o sistema operacional e a rea de memria do processo somente ocorre quando o processo
est presente na memria real.
Atualmente, o swapping tradicional usado em poucos sistemas. Ele requer muito
tempo de swapping e prov muito pouco tempo de execuo para os processos para ser uma
soluo razovel de gerenciamento de memria. Verses modificadas de swapping, entretanto,
so encontradas em muitos sistemas.
Uma verso modificada de swapping encontrada em muitas verses de UNIX
(mais antigas). Normalmente, o swapping desabilitado, mas inicializado assim que muitos
processos esto rodando, e um certo limiar de quantidade de memria em uso atingido. Se a
carga do sistema reduzir, o swapping novamente desabilitado.
O IBM-PC original (devido ao processador 8086/8088) fornecia pouco suporte do
hardware para mtodos mais avanados de gerenciamento de memria. Os sistemas
operacionais da poca tambm tiravam muito pouco proveito do que o hardware poderia
fornecer em termos de suporte para o gerenciamento de memria. Entretanto, o swapping

usado por vrios sistemas operacionais em PCs para permitir que vrios processos estejam em
execuo concorrentemente. Um exemplo o Microsoft Windows, que suporta execuo
concorrente de processos em memria. Se um novo processo carregado e a memria
insuficiente, um processo mais antigo retirado para o disco. Este SO, entretanto, no prov
swapping completo, uma vez que os processos dos usurios, e no o escalonador, que decidem
se hora de trocar um processo em memria por outro em disco. Qualquer processo em disco
permanece l at que um processo executando o escolha para execuo. A verso mais nova do
Windows, o NT (e hoje tambm, o Windows 95), faz uso dos recursos avanados da MMU
encontrada nos PCs de hoje, que foram introduzidos com o processador Intel 80386.

3.4Alocao Contgua de Memria


A memria principal deve acomodar tanto o sistema operacional como os processos
dos usurios. A memria usualmente dividida em duas parties, uma para o sistema
operacional residente, e outra para os processos dos usurios. possvel que o sistema
operacional fique alocado tanto no incio da memria, quanto no fim. O principal fator que afeta
esta deciso a localizao do vetor de interrupes. Como em geral o vetor de interrupes
est nas posies de memria mais baixas, comum colocar o SO no incio da memria. A
figura 3.4 ilustra possveis configuraes de posicionamento do SO.
Sistema
Operacional
em RAM

Sistema
Operacional
em RAM

Programa do
Usurio

a
Programa do
Usurio

Programa do
Usurio

Livre

Livre
b
c

Sistema
Operacional
em ROM

b
d

Livre
Device Drivers
em ROM

a = endereo de fim da rea do SO e incio do programa do usurio


b = endereo de fim do programa do usurio e incio do espao livre
c = endereo de fim da memria total
d = endereo de fim do espao livre e incio da rea do SO

Figura 3.4 - Trs maneiras de organizar a memria

O terceiro esquema da figura 3.4 apresenta algumas rotinas em ROM. Esta a


configurao bsica do IBM-PC. Alguns sistemas operacionais mais modernos podem
completamente ignorar as rotinas em ROM (BIOS Basic Input Output System Sistema
Bsico de Entrada e Sada) do PC, que so usadas apenas durante o processo de boot do sistema
operacional.

3.4.1Alocao com Partio nica


O esquema mais simples de gerenciamento de memria possvel ter apenas um
processo em memria a qualquer momento, e permitir que ele use toda a memria disponvel.
Os sistemas mais antigos da dcada de 60 deixavam a mquina sob controle exclusivo do
programa do usurio, que era carregado de uma fita ou de um conjunto de cartes (mais tarde de
um disco). Esta abordagem no mais usada, mesmo nos computadores pessoais mais baratos,
porque desse modo cada programa deve conter os device drivers para todos os dispositivos que
ele ir acessar.
Quando o sistema est organizado desta forma, somente um processo pode estar
rodando por vez. O usurio digita um comando no console, e o sistema operacional carrega do
disco e executa o programa desejado. Quando o programa termina, o sistema operacional
novamente apresenta um prompt para o usurio, esperando por um novo comando. A execuo
de um novo programa ir sobrepor o contedo da memria que foi usada pelo programa
anterior.
Apesar de aparentemente no existirem problemas em sistemas monoprogramados,
no se deve esquecer que o usurio tem controle total da memria principal. A memria
dividida entre uma poro contendo as rotinas do SO, outra com o programa do usurio, e outra
poro no usada. A questo de proteo quanto possibilidade do programa do usurio
escrever sobre as regies de memria do SO. Se isso acontecer, ele pode destruir o SO. Se isso
for fatal para o programa e o usurio no puder continuar a execuo, ento ele perceber algo
errado, corrigir o programa e tentar novamente. Nessas circunstncias, a necessidade de
proteo para o SO no to aparente.
Mas se o programa do usurio destruir o SO de forma menos drstica, como por
exemplo, a mudana de certas rotinas de I/O, ento o funcionamento das rotinas pode ficar
completamente s avessas. O job continuar rodando. Se os resultados no puderem ser
analisados em tempo de execuo, um grande tempo de mquina ser desperdiado. Pior ainda,

algumas vezes o funcionamento errado no facilmente perceptvel, levando a crer que a


execuo do job est correta. Uma situao ainda mais crtica seria o SO ser modificado de
forma que suas rotinas acabem por destruir o sistema como um todo, como no caso de uma
rotina de acesso a disco acabar escrevendo em regies de disco erradas, escrevendo sobre o
prprio cdigo do SO no disco, ou ainda destruir informaes vitais do disco (tabelas de
alocao, parties, etc.).
Est claro que o SO deve ser protegido do usurio. Proteo pode ser implementada
simplesmente atravs de um recurso chamado boundary register (registrador de limite),
existente em algumas CPUs, conforme ilustrado na figura 3.5.

Sistema
Operacional

0
a

CPU

rea do
programa do
usurio

boundary
register
a

b
Espao livre
c

Figura 3.5 - Proteo de memria em sistemas monousurio

O boundary register contm o endereo da memria mais alta usada pelo SO. Cada
vez que um programa do usurio faz referncia a um endereo de memria, o registrador de
limitao verificado para certificar que o usurio no est prestes a escrever sobre a rea de
memria do SO. Se o usurio tenta entrar no cdigo do SO, a instruo interceptada e o job
terminado com uma mensagem de erro apropriada. Entretanto, claro que o programa do
usurio eventualmente precisa chamar certas funes que esto no cdigo do SO. Para isso o
usurio usa uma instruo especfica com a qual ele requisita servios do SO (uma instruo de
chamada em modo supervisor - supervisor call). Por exemplo, o usurio desejando ler da
unidade de fita vai disparar uma instruo requisitando a operao ao SO, que executar a
funo desejada e retornar o controle ao programa do usurio.
Entretanto,

conforme

SOs

ficaram

mais

complexos

tornaram-se

multiprogramados, foi necessrio implementar mecanismos mais sofisticados para proteger as


regies de memria dos usurios uns dos outros. O registrador de limitao (boundary register)

pode ser implementado atravs do registrador de relocao, conforme vimos anteriormente.


Uma vez que o sistema de memria da mquina sempre assume que o valor do registrador de
relocao corresponde ao endereo de memria lgico 0 visto pelos programas, no h
necessidade de um registrador de limitao que aponte para o ltimo endereo de memria do
SO.
Com a adio de mais um registrador, de limite superior, podemos garantir ainda
que um processo de usurio no sobrescreva reas de memria de outros processos. Assim, o
registrador de relocao contm o menor endereo de memria que o processo pode acessar, e o
registrador de limitao contm a faixa de endereos (quantidade) que o processo pode
enderear a partir do registrador de relocao. Essa situao mostrada na figura 3.6.

Sistema
Operacional

0
1432

rea do
programa do
usurio

CPU

1432
7000
8432

registrador
de relocao
registrador
de limite

Espao livre

Figura 3.6 Suporte do hardware para registradores de relocao e limite

Com este esquema, toda vez que um processo solicita acesso memria, ele deve
passar pela verificao dos dois registradores, conforme a figura 3.7:

Registrador
de limite
superior

CPU

Endereo
lgico

Registrador
de relocao

sim

<

Endereo
fsico
Memria

no

Exceo: erro de
endereamento

Figura 3.7 Funcionamento do hardware para os registradores de relocao e limite

Quando o escalonador de CPU seleciona outro processo para execuo na fila de


ready, o despachador carrega os registradores de relocao e de limite superior com os valores
corretos, da mesma forma que ele o faz com os demais registradores durante a troca de
contexto. Como todo endereo de memria gerado pela CPU verificado com os valores dos
registradores, ambos o sistema operacional e os processos dos outros usurios esto protegidos
das tentativas do processo executando tentar modificarsuas respectivas reas de memria.
Vale notar que o registrador de relocao fornece um esquema eficiente para
permitir que o tamanho do SO em memria cresa ou diminua dinamicamente. Esta
flexibilidade desejvel em muitas situaes. Por exemplo, o SO contm cdigo e buffers para
os device drivers. Se um device driver (ou um outro servio do SO) no usado com
freqncia, interessante que suas reas de cdigo e dados sejam liberadas para uso pelos
programas dos usurios. Este tipo de cdigo chamado de cdigo transiente (ao contrrio de
residente), pois ele carregado e descarregado da memria conforme sua necessidade. Dessa
forma, ao carregar um driver deste tipo, o sistema operacional muda de tamanho em memria, e
o registrador de relocao resolve o problema.
Um exemplo de sistema operacional moderno que possui drivers carregados e
descarregados da memria dinamicamente o Sun Solaris 2.5. Toda vez que um determinado
driver (ou at mesmo partes do SO importantes, como os protocolos de rede TCP/IP, etc.) fica
um certo tempo sem ser usado por nenhum processo de usurio, ele automaticamente
descarregado da memria. Assim que um processo faz alguma chamada que utiliza este driver,
o SO automaticamente o carrega. Outro sistema operacional que suporta este tipo de driver o

Linux, que incluiu este recurso a partir da verso de kernel 2.0.0.

3.5Memria Virtual
3.5.1Paginao
3.5.2Algoritmos de Paginao
3.5.3Segmentao

Potrebbero piacerti anche