SlideShare uma empresa Scribd logo
1 de 204
Baixar para ler offline
Sistemas de Informação 
Sistemas Operacionais 
Daniel Paz de Araújo 
professor@danielpaz.net
1. Introdução
1.1 Conceito básico 
Em torno de um computador existem usuários com problemas 
para serem resolvidos, por programas específicos. 
Para um melhor aproveitamento do hardware, vários usuários 
compartilham simultaneamente o computador. 
Os programas podem apresentar necessidades conflitantes, pois 
disputam os recursos do equipamento. 
Exemplo: disco, memória, impressora.
1.1 Conceito básico 
O S.O. é uma camada de software colocada entre o hardware e os programas que 
executam tarefas para os usuários. 
É responsável pelo acesso aos periféricos; sempre que um programa necessita de 
algum tipo de operação de entrada e saída. 
Como todos os acessos aos periféricos são feitos através do sistema operacional, 
ele pode controlar qual programa está acessando qual recurso. 
É possível, então, obter uma distribuição justa e eficiente de recursos.
1.1 Conceito Básico 
Figura 1.1: Sistema Operacional
1.2 Objetivos do sistema operacional 
O sistema operacional procura tornar a utilização do computador, ao mesmo 
temo, mais eficiente e mais conveniente. 
Maior eficiência significa mais trabalho obtido no mesmo hardware, através da 
distribuição de seus recursos entre os programas. Exemplo: espaço na memória, 
tempo de processador, impressora, espaço em disco, etc. 
Maior conveniência significa diminuir o tempo necessário para a construção dos 
programas, escondendo-se do programador detalhes do hardware. Exemplo: 
tipos de interface, acesso a periféricos, etc.
1.2.1 Tipos de serviços 
Execução de programas: o sistema operacional recebe o nome do 
arquivo, aloca memória para o programa, copia o conteúdo para a 
memória principal e inicia sua execução. 
Armazenamento de arquivos: permite a criação, escrita, leitura e 
exclusão de arquivos, além de operações como renomear, obter o 
tamanho, data de criação e outras informações a seu respeito. 
Acesso a periféricos: alocação, leitura, escrita e liberação, além de 
obtenção e alteração de informações a seu respeito.
1.2.1 Tipos de serviços 
À medida que diversos usuários compartilham o computador, 
passa a ser interessante saber quanto de mais recurso cada 
usuário necessita. 
Pode-se utilizar essa informação para calcular o valor a ser 
cobrado pelo uso do computador. 
Na busca de um melhor aproveitamento do hardware, diversos 
usuários podem compartilhar um computador. 
Cabe ao sistema operacional garantir que cada usuário possa 
trabalhar sem sofrer interferência danosa dos demais.
1.3 S.O. na visão do usuário 
A arquitetura de um sistema operacional corresponde à imagem 
que o usuário tem do sistema, a forma como ele percebe o sistema. 
Essa imagem é definida pela interface através da qual o usuário 
acessa os serviços do sistema operacional. 
Essa interface, assim como a imagem, é formada pelas chamadas 
de sistemas e pelos programas de sistema.
1.3.1 Chamadas de sistema 
Os programas solicitam serviços ao sistema operacional através das chamadas de 
sistema. 
Elas são semelhantes às chamadas de sub-rotinas, contudo enquanto estas são 
transferências para procedimentos normais do programa, as chamadas de 
sistema transferem a execução para o sistema operacional. 
Através de parâmetros, o programa informa exatamente o que necessita e o 
retorno da chamada de sistema, assim como retorno de uma sub-rotina, faz com 
que a execução do programa seja retomada a partir da instrução que segue a 
chamada. Exemplo: abertura de um arquivo.
1.3.1 Chamadas de sistema 
A parte do sistema operacional responsável por implementar as chamadas de 
sistema é normalmente chamada de núcleo ou kernel. 
Os principais componentes do kernel são a gerência de processador, a gerência 
de memória, o sistema de arquivos e a gerência de entrada e saída. 
Muitos sistemas operacionais são implementados em camadas, primeiro um 
componente de software chamado micronúcleo ou microkernel implementa os 
serviços mais básicos associados a sistemas operacionais. Em cima do microkernel, 
usando seus serviços, o kernel propriamente dito implementa os demais serviços.
1.3.1 Chamadas de sistema 
Figura 1.2: Organização do sistema em kernel e microkernel
1.3.2 Programas de sistema 
Os programas de sistema, alguma vezes chamados de utilitários, são programas 
normais executados fora do kernel do sistema operacional. 
Esses programas implementam tarefas básicas para a utilização do sistema e 
muitas vezes são confundidos com o próprio sistema operacional. 
Como implementam tarefas essenciais para a utilização do computador, são, em 
geral, distribuídos pelo próprio fornecedor do sistema operacional. 
Exemplos são os utilitários para manipulação de arquivos: programas para listar 
arquivo, imprimir, copiar, renomear, listar conteúdo de diretório, entre outros.
1.3.2 Programas de sistema 
O mais importante programa de sistema é o interpretador de 
comandos. 
Sua tarefa é receber comandos do usuário e executá-los. 
Para isso ele recebe as linhas tecladas pelo usuário, analisa seu 
conteúdo e executa o comando teclado. 
A execução do comando, na maioria das vezes, vai exigir uma ou 
mais chamadas de sistema. 
Exemplo: listagem de diretório
1.3.2 Programas de sistema 
Os mesmos conceitos sobre o interpretador de comandos é igualmente válido 
para a situação em que o sistema operacional oferece uma interface gráfica de 
usuário (GUI - graphical user interface). 
A única diferença está na comodidade para o usuário, que passa a usar ícones, 
menus e mouse no lugar de digitar comandos textuais. 
Programadores utilizam principalmente editores de texto e compiladores. 
Usuários finais utilizam aplicativos e ferramentas de apoio. O sistema operacional 
propriamente dito fica escondido, longe da percepção do usuário comum.
1.4 S.O. na visão de projeto 
Na visão de projeto, o mais importante é como o sistema está 
organizado internamente. A organização de um sistema 
operacional corresponde à forma como ele implementa os vários 
serviços. 
Dois tipos de eventos ativam o sistema operacional: uma chamada 
de sistema ou uma interrupção de periférico. 
É possível que a chamada de sistema envolva o acesso a um 
periférico. Nesse caso, o programa deverá esperar até que o 
periférico conclua a operação solicitada.
1.4 S.O. na visão de projeto 
Em função das chamadas de sistema, o sistema operacional envia comandos para 
os controladores dos periféricos. 
O controlador deve informar ao sistema operacional quando a operação estiver 
concluída. 
Isso é feito por intermédio de uma interrupção, quando o processador para o que 
está fazendo e passa a executar uma rotina específica do sistema operacional. 
Como a interrupção do periférico avisa o término de alguma operação de entrada 
e saída, possivelmente uma chamada de sistema foi concluída. Nesse caso, um 
programa à espera de resposta poderá ser liberado.
1.5 Histórico de sistemas operacionais 
Na década de 1940 não existia sistema operacional. 
O programador também é o operador do computador. 
Um programa tem total controle sobre a máquina, e acessa diretamente os 
periféricos. 
No máximo, existe uma biblioteca com rotinas de entrada e saída já programadas. 
Começou-se a utilizar operadores profissionais, assim o programador não mais 
opera o computador durante a execução de seu programa. Ele entrega ao 
operador o seu job.
1.5 Histórico de sistemas operacionais 
Entretanto, o tempo de preparação para a execução de um job 
continua grande. É necessário retirar as fitas magnéticas, cartões 
de listagem do job que terminou e preparar o próximo. 
Para diminuir esse tempo entre jobs, eles passam a ser agrupados 
em lotes. Em um mesmo lote, ou batch, são colocados jobs com 
necessidades semelhantes. 
Essa é a origem do termo sistema em batch. 
Um mesmo job pode exigir a execução de vários programas. Cada 
uma dessas etapas é chamada de step.
1.5 Histórico de sistemas operacionais 
Na década de 1950 surgiram os primeiros monitores residentes. O monitor 
residente é um tipo de programa que fica o tempo todo na memória. Quando um 
programa em execução termina, ele avisa o monitor que então, carrega 
automaticamente o próximo programa e inicia a execução dele. 
O monitor residente também é o local indicado para as rotinas de acesso aos 
periféricos, e são utilizadas por todos os programas. Desta forma as aplicações 
não precisam mais acessar diretamente os periféricos, apenas chamar a rotina 
apropriada dentro do monitor. 
Esse é o início da ideia de chamada de sistema.
1.5 Histórico de sistemas operacionais 
Na década de 1960 surgiu o conceito de multiprogramação. 
Em geral, periféricos são dispositivos eletromecânicos e 
trabalham na faixa de milissegundo. Ao mesmo tempo, o 
processador é um dispositivo eletrônico, que trabalha na faixa de 
microssegundo. Por exemplo, enquanto é feito um único acesso à 
leitora de cartões, poderiam ser executadas 10.000 instruções de 
máquina ou mais. 
A solução imaginada foi manter diversos programas na memória 
principal ao mesmo tempo. Quando um dos programas está 
esperando a conclusão da entrada ou saída, outro programa inicia 
sua execução.
1.5 Histórico de sistemas operacionais 
Duas inovações de hardware possibilitaram o desenvolvimento da 
multiprogramação. 
Interrupções: quando um comando é enviado para um periférico, 
imediatamente o sistema operacional inicia a execução de outro 
programa. É através de uma interrupção que o periférico avisa o 
sistema operacional quando o acesso tiver sido concluído. Pode-se 
fazer com que o processador fique em um laço, consultando a 
interface do periférico, até que a operação esteja concluída.
1.5 Histórico de sistemas operacionais 
Discos magnéticos: vários jobs são lidos de cartão perfurado ou 
fita magnética para o disco. Como o disco permite acesso direto a 
qualquer posição, é possível ler parte do primeiro job e do 
segundo job. À medida que, em sua função de execução, um job 
solicita a leitura de mais dados, eles são buscados no disco. 
Com a utilização de disco magnético, não havia mais a necessidade 
de reunir jobs semelhantes em lotes. O termo batch passou então 
a designar um sistema no qual não existe interação entre o 
usuário e a execução do programa. Mais modernamente o termo 
batch foi substituído por "execução em background".
1.5 Histórico de sistemas operacionais 
Na década de 1970 ocorreu a disseminação de sistemas 
timesharing. Em um ambiente com multiprogramação, diversos 
programas dividem o tempo do processador. 
Em um ambiente de timesharing, além da multipogramação, cada 
usuário possui um terminal onde ele interage com o programa em 
execução tendo a sensação de possuir o computador apenas para 
seus programas.
1.5 Histórico de sistemas operacionais 
Na década de 1980 houve uma enorme disponibilidade de 
microcomputadores. 
No início, os sistemas operacionais para microcomputadores eram 
bastante simples, lembrando até o velho monitor residente. 
À medida que o hardware dessas máquinas foi melhorado, o 
mesmo aconteceu com o sistema operacional.
1.5 Histórico de sistemas operacionais 
A maioria das aplicações comerciais é hoje construída em torno 
de bancos de dados. Ainda que a maioria dos sistemas 
gerenciadores de bancos de dados sejam implementados fora do 
sistema operacional, este deve oferecer algum suporte. 
Em um sistema operacional distribuído, vários computadores 
estão interconectados por meio de uma rede de comunicação de 
algum tipo. É possível, a partir de um dos computadores, acessar 
recursos em outros.
1.5 Histórico de sistemas operacionais 
Os sistemas operacionais de tempo real, são usados no suporte às aplicações 
submetidas a requisitos de natureza temporal. Nesses sistemas, os resultados 
devem estar corretos e não somente do ponto de vista lógico, mas também 
devem ser gerados no momento correto. Exemplo: lavadoras de roupa, tráfego 
aéreo. 
À medida que são desenvolvidos computadores com diversos processadores, 
passa a ser necessário rever aspectos básicos dos sistemas operacionals. Por 
exemplo, agora existe um paralelismo real a ser aproveitado. diversos 
programas podem ser executados realmente em paralelo, mas nem todos os 
processadores possuem acesso a toda a memória.
Bibliografia 
OLIVEIRA, R. S. de; CARISSIMI, A. da S. e TOSCANI, S.S. Sistemas 
Operacionais. Porto Alegre. Bookman, 2008.
2. Multiprogramação
2.1 Mecanismo básico 
Em um sistema multiprogramado diversos programas são 
mantidos na memória ao mesmo tempo. 
A maioria dos programas não precisa de toda a memória do 
computador. Muitos programas ocupam uma pequena parcela da 
memória principal disponível. 
Sem multiprogramação, a memória não ocupada por um programa 
ficaria sem utilização. 
Com vários programas na memória, esse recurso é mais bem 
aproveitado.
2.1 Mecanismo básico 
Figura 2.1: Memória em um sistema com multiprogramação
2.2 O conceito de processo 
Em sistemas operacionais é conveniente diferenciar um programa de sua 
execução. Por exemplo, o mesmo programa pode estar sendo executado por 
vários usuários ao mesmo tempo. 
Na maioria das vezes, um processo é definido como "um programa em 
execução". 
Um programa é uma sequência de instruções e é passivo dentro do sistema, não 
alterando o próprio estado. 
O processo é um elemento ativo que altera o seu estado, à medida que executa 
um programa. É o processo que faz chamadas de sistema ao executar programas.
2.3 Ciclos de um processo 
Processos são criados e destruídos, porém o momento e a forma 
com que isso ocorre depende do sistema operacional. 
Algum sistemas trabalham com um número fixo de processo, 
sendo criados na inicialização do sistema e destruídos quando o 
mesmo é desligado. 
Outra forma é sua associação com uma sessão de trabalho, 
criando processos no momento do acesso do usuário ao sistema e 
destruindo-os quando é executada o final da sessão.
2.3 Ciclos de um processo 
A forma mais flexível de operação é permitir que os processos 
possam ser criados livremente, através de chamadas do sistema. 
Além da chamada de sistema "cria processo", serão necessárias 
chamadas para "autodestruição do processo"e também para a 
"eliminação de outro processo". 
A maioria dos processos de um sistema executa programas do 
usuário. Entretando alguns podem realizar tarefas de sistemas. 
São processos do sistema (daemon).
2.3 Ciclos de um processo 
Por exemplo, para evitar conflitos na utilização da impressora, muitos sistemas 
trabalham com uma técnica chamada spooling. 
Para imprimir um arquivo, o processo de usuário deve colocá-lo em um diretório 
especial. Um processo do sistema copia os arquivos desse diretório para a 
impressora. 
Dessa forma, um processo de usuário nunca precisa esperar a impressora ficar 
livre, uma vez que ele não envia os dados para a impressora, mas sim para o disco. 
O processo que envia os dados para a impressora não está associado a nenhum 
usuário.
2.3 Ciclos de um processo 
Após ter sido criado, o processo passa a ocupar o processador. Em determinados 
momentos, ele deixa de fazer isso para realizar uma operação de E/S. 
Os momentos em que um processo deseja ocupar o processador, são chamados 
de ciclos de processador. 
Quando o processo está esperando por uma operação de E/S, ele está em 
um ciclo de E/S. 
A chamada de sistema é o evento que termina o ciclo de processador em 
andamento e inicia um ciclo de E/S. 
A conclusão da chamada de sistema faz o caminho inverso.
2.3 Ciclos de um processo 
Um processo que utiliza muito processador é chamado de cpu-bound. 
O seu tempo de execução é definido principalmente pelo 
tempo dos seus ciclos de processador. 
Por outro lado, um processo que utiliza muita E/S é chamado de 
i/o-bound (input/output-bound). Nesse caso, o tempo de execução 
é definido principalmente pela duração das operações de E/S. 
Não existe uma quantificação precisa para essas definições.
2.4 Relacionamento entre processos 
Alguns sistemas suportam o conceito de grupos de processos. 
Se processos são criados através de chamada de sistema, pode-se 
considerar como pertencentes ao mesmo grupo todos os 
processos criados pelo mesmo processo. 
O conceito de grupo permite que operações possam ser aplicadas 
sobre todo um conjunto de processos, e não apenas sobre 
processos individuais. 
Por exemplo, os processos pertencentes a um mesmo grupo 
podem compartilhar os mesmos direitos perante o sistema.
2.4 Relacionamento entre processos 
Em muitos sistemas os processos são criados por outros 
processos, pelas chamadas de sistema. Nesse caso, é possível 
definir uma hierarquia de processos. 
O processo que faz a chamada de sistema é chamado de processo 
pai, enquanto o processo criado é chamado de processo filho. 
Um mesmo processo pai pode estar associado a vários processos 
filhos. Os processos filhos, por sua vez, podem criar outros 
processos.
2.4 Relacionamento entre processos 
Figura 2.2: Hierarquia de processos
2.4 Relacionamento entre processos 
À medida que processos são criados e destruídos, nodos são 
acrescentados ou removidos da árvore, respectivamente. 
O sistema pode definir, por exemplo, o que fazer quando um processo 
com filhos é destruído. Pode-se definir que, quando um processo é 
destruído, todos os processos que derivam dele também são destruídos. 
Outra solução é manter o nodo que representa o processo destruído, até 
que todos os seus descendentes também terminem. 
Uma terceira solução é vincular os processos que são filhos do processo 
destruído com o processo pai daquele, isto é, com o "processo avô" deles.
2.5 Estados de um processo 
Em máquinas multiprocessadoras existem diversos 
processadores. Nesse caso, diversos processos executam ao 
mesmo tempo. Porém, essa não é a situação mais comum. 
Vamos supor que existe um único processador no computador. 
Nesse caso é necessário manter uma fila com os processos aptos a 
ganhar o processador. 
Essa fila é chamada "fila de aptos" (ready queue).
2.5 Estados de um processo 
A figura 2.3 ilustra essa situação. 
O processo 1 ocupa o processador, enquanto os processos 2 e 3 esperam na fila 
de aptos. 
Os processos na fila do processador estão em estado de apto (ready). 
Um único processo ocupa o processador a cada instante. 
O processo que ocupa o processador está no estado executando (running). 
Na figura, o processo 1 está no estado executando, enquanto os processos 2 e 3 
estão no estado apto.
2.5 Estados de um processo 
Figura 2.3: Fila de processos esperando pelo processador
2.5 Estados de um processo 
A figura 2.4 mostra o diagrama de estados de um processo. 
No estado executando, um processo pode fazer chamadas de 
sistema. 
Até a chamada de sistema ser atendida, o processo não pode 
continuar sua execução. Ele fica bloqueado e só volta a disputar o 
processador após a conclusão da chamada. 
Enquanto espera pelo término da chamada de sistema, o processo 
está no estado bloqueado (blocked).
2.5 Estados de um processo 
Figura 2.4: Diagrama de estados de um processo
2.5 Estados de um processo 
A mudança de estado de qualquer processo é iniciada por um evento. Esse evento 
aciona o sistema operacional, que, então, altera o estado de um ou mais 
processos. 
A transição de estado executando para bloqueado é feita através de uma 
chamada de sistema. 
Ele fica bloqueado até o atendimento e, com isso, o processador fica livre. O 
sistema operacional então seleciona um processo na fila de aptos para receber o 
processador e altera seu estado para executando. 
O módulo do sistema operacional que faz essa seleção é chamado escalonador 
(scheduler).
2.5 Estados de um processo 
Algumas chamadas de sistema são muito rápidas. Por exemplo, a 
leitura da hora atual. 
Não existe acesso a periférico, mas apenas consulta à variáveis do 
próprio sistema operacional. 
Nesse caso, o processo não precisa voltar para a fila de aptos: ele 
simplesmente retorna para a execução após a conclusão de 
chamada, o que implica um caminho do estado bloqueado para o 
estado executando.
2.5 Estados de um processo 
Muitos sistemas procuram evitar que um único processo 
monopolize a ocupação do processador. 
E um processo está há muito tempo no processador, ele volta para 
o fim da fila de aptos. 
Um novo processo da fila de aptos ganha o processador e assim 
cada processo tem a chance de executar um pouco. 
Esse mecanismo cria um caminho entre o estado executando e o 
estado apto (a figura 2.5 mostra o grafo de estados dos processos 
com esses novos caminhos).
2.5 Estados de um processo 
Figura 2.5: Novo diagrama de estados de um processo
2.6 Gerência de filas 
O tempo de acesso a um periférico é muito grande se comparado 
aos tempos de processador. 
Se houver mais de uma solicitação for para o mesmo periférico, 
não é possível enviar o comando imediatamente, pois a maioria dos 
controladores de periféricos não suporta dois comandos 
simultâneos. 
O segundo processo terá que esperar o periférico ficar livre. 
De qualquer maneira, o processador ficou livre; um terceiro 
processo será retirado da fila de aptos e passará a ocupar o 
processador.
2.6 Gerência de filas 
Quando uma solicitação é feita, é preciso verificar a fila do 
periférico. 
Se ela estiver vazia, o periférico está livre. O pedido é inserido 
na fila, e o comando é enviado para o controlador. 
Caso contrário, o periférico está ocupado e o pedido é 
inserido na fila, mas nada é enviado ao controlador.
2.6 Gerência de filas 
A figura 2.6 ilustra um momento específico dentro do sistema. 
● O processo 1 está executando. Na fila de aptos, esperando pelo 
processador, estão os processos 2 e 3. 
● A impressora está livre. 
● Existe um acesso em andamento na unidade de disco 0, feito pelo processo 
4. 
● O processo 5 também solicitou um acesso à unidade 0, mas deve esperar a 
conclusão do pedido em andamento. 
● Os processos 4 e 5 estão bloqueados, ou seja, não disputam processador. 
● A unidade de disco 1 está sendo acessada em função de um pedido do 
processo 6.
2.6 Gerência de filas 
Figura 2.6: Filas do sistema operacional
2.7 Mecanismo de interrupções 
O mecanismo de interrupções é um recurso comum dos 
processadores de qualquer porte. Ele permite que um controlador 
de periférico chame a atenção do processador. 
Analogia entre as interrupções de hardware e o telefone. 
Uma interrupção sempre sinaliza a ocorrência de algum evento. 
Quando ela acontece, desvia a execução da posição atual de 
programa para uma rotina específica. 
Essa rotina, responsável por atender a interrupção, é chamada 
de tratador de interrupção.
2.7 Mecanismo de interrupções 
Para que a execução do programa interrompido não seja comprometida pela 
interrupção, é necessário que nenhum registrador seja alterado. 
Alguns processadores salvam automaticamente todos os registradores quando 
ocorre uma interrupção; outros, salvam apenas alguns, cabendo à rotina que 
atende à interrupção salvar os demais registradores. 
O local mais indicado é a pilha de execução. É usual o processador dispor de uma 
instrução tipo retorno de interrupção que repõe o conteúdo original dos 
registradores e faz o processador retomar a execução do programa interrompido.
2.7 Mecanismo de interrupções 
A função básica de um controlador de periférico é conectar o dispositivo em 
questão com o processador. 
Através do barramento, o processador é capaz de realizar operações do tipo "lê 
dados", "escreve dados", "reinicializa", "lê status" e "escreve comando". 
O controlador é responsável por traduzir essas operações em uma sequência de 
acionamentos eletrônicos, elétricos e mecânicos capazes de realizar a operação 
solicitada. 
Para isso, o controlador deve saber como o periférico funciona. Daí resulta que 
cada tipo de periférico necessita de um controlador diferente.
2.7 Mecanismo de interrupções 
A figura 2.7 mostra o diagrama de tempo resultante quando 
interrupções são empregadas para implementar E/S. 
Após enviar o comando para o controlador, o processador segue a 
execução do programa. 
Quando a operação é concluída, o controlador gera uma 
interrupção. 
O processador, então, lê os resultados do controlador.
2.7 Mecanismo de interrupções 
Figura 2.7: Linha de tempo quando interrupção é usada para implementar E/S
2.7 Mecanismo de interrupções 
A forma mais simples de identificar a origem de uma interrupção é 
associar a cada controlador um tipo diferente de interrupção. 
Dessa forma, o controlador não somente interrompe o 
processador, mas também informa qual o tipo de interrupção. 
A maioria dos processadores admite diversos tipos de 
interrupções. Cada tipo de interrupção é identificado por um 
número. Por exemplo, de 0 (zero) a 255.
2.7 Mecanismo de interrupções 
Existem momentos em que um programa não pode ser interrompido. Por 
exemplo, o programa pode estar alterando variáveis que também são acessadas 
pelo tratador de interrupções. 
A solução para esse problema é desligar o mecanismo de interrupções 
temporariamente, enquanto o programa realiza uma tarefa crítica que não pode 
ser interrompida. 
Os processadores normalmente possuem instruções para habilitar e desabilitar 
interrupções. 
Enquanto as interrupções estiverem desabilitadas, elas são ignoradas pelo 
processador. Elas não são perdidas, apenas ficam pendentes.
2.7 Mecanismo de interrupções 
É comum a existência de uma relação de prioridades entre os 
diferentes tipos de interrupções. 
Vamos supor que um dado processador atribui prioridade 
decrescente do tipo 0 até o tipo 255. Nesse caso, quando ocorre 
uma interrupção tipo 10, o processador automaticamente 
desabilita interrupções dos tipos 10 a 255 até que o atendimento 
da interrupção tipo 10 tenha sido concluído. 
Caso ocorra, durante esse intervalo de tempo, uma interrupção do 
tipo 5, ela é imediatamente reconhecida pelo processador. Assim, 
o tratador de interrupção tipo 10 é interrompido e o tratador de 
interrupções tipo 5 ativado.
2.7 Mecanismo de interrupções 
Figura 2.8: Ativação em cascata de tratadores de interrupção
2.7 Mecanismo de interrupções 
O endereço de um tratador de interrupção é chamado de vetor de 
interrupção que "aponta" para a rotina de atendimento da mesma. 
Em geral, existe uma tabela na memória com todos os vetores de 
interrupção, ou seja, com os endereços das rotinas responsáveis 
por tratar os respectivos tipos de interrupção. 
A ocorrência de uma interrupção dispara no processador 
uma sequência de atendimento. 
Toda a sequência é executada pelo hardware, comandada pela 
unidade de controle do processador.
2.7 Mecanismo de interrupções 
Figura 2.9: Tabela dos vetores de interrupção
2.7 Mecanismo de interrupções 
Interrupções de software (traps) são causadas pela execução de 
uma instrução específica para isso, tendo como parâmetro o 
número da interrupção que deve ser ativada. 
O uso mais comum para interrupções de software é a 
implementação das chamadas de sistema, por meio das quais os 
programas de usuário solicitam serviços ao sistema operacional. 
O endereço armazenado nas tabelas de vetores de interrupção 
deve mudar conforme a versão do sistema operacional, que na sua 
inicialização fica encarregado de colocar os endereços certos na 
tabela.
2.7 Mecanismo de interrupções 
As interrupções por erro, ou interrupções de exceção 
acontecem quando o processador detecta algum tipo de 
erro na execução do programa, como por exemplo, uma 
divisão por zero ou o acesso a uma posição de memória que 
na verdade não existe. 
O procedimento de atendimento a essa classe de 
interrupção é igual ao descrito anteriormente.
2.8 Proteção entre processos 
Na multiprogramação, diversos processos compartilham o 
computador. 
É necessário que o sistema operacional ofereça proteção aos 
processos e garanta a utilização correta do sistema. Por 
exemplo, um processo de usuário não pode formatar o disco. 
Também não se pode permitir que um processo entre em um 
laço infinito e, com isso, monopolize a utilização do 
processador.
2.8.1 Modos de operação do processador 
O sistema operacional é responsável por implementar uma proteção 
apropriada para o sistema e para isso, é necessário o auxílio do processador 
(hardware). 
A forma usual é definir dois modos de operação: 
1. Modo usuário: algumas instruções não podem ser executadas. 
2. Modo supervisor: não existem restrições, e qualquer instrução pode ser 
executada. Essas instruções são chamadas privilegiadas. 
Se um processo de usuário tentar executar uma instrução privilegiada, 
o hardware automaticamente gera uma interrupção e aciona o sistema 
operacional que poderá abortar o processo.
2.8.2 Proteção dos periféricos 
Para proteger os periféricos, as instruções de E/S são tornadas privilegiadas. 
A única forma de o processo de usuário realizar uma operação de E/S é 
através de uma chamada de sistema. 
Muitas arquiteturas oferecem uma instrução chamada de interrupção de 
software ou trap, que quando executada, apresenta um efeito semelhante 
ao de uma interrupção por hardware, a única diferença sendo o fato de ter 
sido causada pelo software e não por um evento externo vinculado 
ao hardware. 
As interrupções geradas por software também chaveiam o processador para 
o modo supervisor.
2.8.2 Proteção de periféricos 
Figura 2.10: Modos de operação do processador
2.8.3 Proteção da memória 
Para implementar a proteção de memória, o sistema operacional também 
necessita de auxílio da arquitetura. 
Sempre que o sistema operacional vai disparar um processo de usuário, ele 
carrega nos registradores de limite os valores relativos ao processo que vai 
executar. 
Ele coloca no registrador limite inferior o endereço do primeiro byte pertencente 
à área de trabalho do processo e no registrador limite superior é colocado o 
endereço do último byte válido para a sua área. 
A cada acesso à memória, o hardware de proteção compara o endereço gerado 
pelo processador com o conteúdo dos dois registradores limite e se estiver fora 
da área do usuário, é gerada uma interrupção.
2.8.3 Proteção da memória 
Figura 2.11: Proteção de memória com registradores de limite
2.8.3 Proteção da memória 
Algumas arquiteturas fazem o acesso aos periféricos através de posições 
específicas da memória. Essa técnica é chamada de E/S mapeada na 
memória. 
Nesse caso, a proteção da memória também implementa a proteção dos 
periféricos. Basta colocar os endereços dos periféricos fora dos limites da 
área do processo. O processo não será capaz de acessar o periférico sem 
gerar uma interrupção. 
Obviamente, o acesso aos registradores de limite deve ser feito através 
de instruções privilegiadas. Somente o sistema operacional pode alterar 
o seu conteúdo.
2.8.3 Proteção da memória 
Para evitar que um único processo de usuário monopolize a utilização do 
processador, é empregado um temporizador (timer), que é um relógio 
de tempo real, implementado pelo hardware, que gera interrupções de 
tempos em tempos. 
As interrupções do temporizador ativam o sistema operacional que então 
verifica se o processo executado já está há muito tempo com o 
processador. 
Nesse caso, o sistema pode abortar o processo por exceder o limite de 
tempo de execução. 
O controle do temporizador deve ser feito através de instruções 
privilegiadas.
2.8.3 Proteção da memória 
Figura 2.12: Hardware para verificação dos endereços
2.8.3 Proteção da memória 
Muitas arquiteturas não definem apenas dois modos de operação, 
mas vários. 
Em cada modo de operação, também chamado de nível de 
proteção, algumas operações não são permitidas. 
Quanto mais confiável o software, mais direitos ele recebe. 
Com auxílio do hardware e um sistema operacional sem falhas, é 
possível construir sistemas seguros, ou seja, sistemas nos quais não 
ocorram interferências danosas entre usuários.
Bibliografia 
OLIVEIRA, R. S. de; CARISSIMI, A. da S. e TOSCANI, S.S. 
Sistemas Operacionais. Porto Alegre. Bookman, 2008.
3. Programação 
Concorrente
3. Programação concorrente 
Um programa que é executado por apenas um processo é chamado de 
programa sequencial. Nesse caso, existem somente um fluxo de 
controle durante a execução. 
Um programa concorrente é executado simultaneamente por diversos 
processos que cooperam entre si, isso é, trocam informações, o que 
significa trocar dados ou realizar algum tipo de sincronização. É 
necessária a existência de interação entre processos para que o 
programa seja considerado concorrente. 
O termo "programação concorrente" vem do inglês concurrent 
programming, onde concurrent significa "acontecendo ao mesmo tempo" 
ou concomitantemente.
3.1 Motivação 
Um programa concorrente pode apresentar todos os tipos de erros que 
normalmente aparecem em programas sequenciais. Além disso, existem 
os erros associados com as interações entre os processos. 
Mesmo com todas as suas complexidades inerentes, existem muitas 
áreas nas quais a programação concorrente é útil. 
Considere um programa que deve ler registros de um arquivo, colocar 
em um formato apropriado e então enviar para uma impressora física.
3.1.1 Programa sequencial 
Figura 3.1: Programa sequencial acessando arquivo e impressora
3.1.1 Programa sequencial 
Figura 3.2: Linha de tempo do programa sequencial da figura 3.1
3.1.1 Programa sequencial 
Inicialmente, o processo envia um comando para a leitura do arquivo e 
fica bloqueado, o disco então é acionado para realizar a operação de 
leitura. 
Uma vez concluída a leitura, o processo realiza a formatação e inicia 
a transferência dos dados para a impressora. 
Observe o diagrama da figura 3.2, o disco e a impressora nunca 
trabalham simultaneamente, embora não exista nenhuma limitação de 
natureza eletrônica. O programa sequencial é que não consegue ocupar 
ambos.
3.1.2 Programa concorrente 
Figura 3.3: Programa concorrente acessando arquivo e impressora
3.1.2 Programa concorrente 
Figura 3.4: Linha de tempo do programa concorrente da figura 3.3
3.1.2 Programa concorrente 
O programa concorrente é mais eficiente, pois consegue manter o disco e a 
impressora trabalhando simultaneamente. 
O tempo total para realizar a impressão do arquivo é menor quando a solução 
concorrente é empregada. 
Se o processo Leitor for sempre mais rápido, o buffer ficará cheio, e então o 
processo Leitor terá que esperar até que o processo impressor retire algo do 
buffer. 
Por outro lado, se o processo impressor for sempre mais rápido, eventualmente 
o buffer ficará vazio e ele terá que esperar pelo processo leitor.
3.2 Paralelismo 
Na verdade, a maior motivação para a programação concorrente é a engenharia 
de software. 
Aplicações inerentemente paralelas são mais facilmente construídas se 
programação concorrente é utilizada. 
Estão enquadrados nesse grupo, aplicações envolvendo protocolos de 
comunicação, aplicações de supervisão e controle industrial, e como era de se 
esperar, a própria construção de um sistema operacional.
3.2 Paralelismo 
A figura 3.5 ilustra uma rede local na qual existem diversos computadores 
pessoais utilizados pelos usuários e existe um computador dedicado ao papel 
de servidor de impressão na rede. 
O programa "servidor de impressão" deve: receber mensagens pela rede; 
escrever em disco os pedaços de arquivos recebidos; enviar mensagens pela 
rede contendo, por exemplo, resposta às consultas sobre seu estado; ler 
arquivos previamente recebidos; enviar dados para a impressora. 
Todas essas atividades devem ser realizadas simultaneamente.
3.2 Paralelismo 
Figura 3.5: Rede local incluindo um servidor de impressão dedicado
3.2 Paralelismo 
A figura 3.6 mostra uma das possíveis soluções para a organização interna do 
programa concorrente "servidor de impressão". 
Cada círculo representa um processo. 
Cada flecha representa a passagem de dados de um processo para o outro. 
Essa passagem de dados pode ser feita, por exemplo, através de variáveis que 
são compartilhadas pelos processos envolvidos na comunicação.
3.2 Paralelismo 
Figura 3.6: Servidor de impressão como programa concorrente
3.2 Especificação do paralelismo 
É poissível especificar paralelimos através de comandos: 
● create_process: permite a criação de um segundo fluxo de execução, 
paralelo àquele que executou o comando. 
● exit: o fluxo de controle que o executa é imediatamente terminado. 
● wait_process: permite que um fluxo de execução espere outro fluxo 
terminar.
3.2 Especificação do paralelismo 
Figura 3.7: Exemplo contendo os comandos create_process, exit e wait_process
3.2 Especificação do paralelismo 
É importante observar que processos paralelos podem executar em qualquer 
ordem. Algumas possíveis saídas: 
Alo do pai 
Alo do filho 
Alo do filho 
Filho 1 morreu 
Filho 2 morreu 
Alo do pai 
Alo do filho 
Filho 1 morreu 
Alo do filho 
Filho 2 morreu
3.2 Especificação do paralelismo 
Figura 3.8: Diagrama de tempo associada com o programa da figura 3.7
3.2 Especificação do paralelismo 
Figura 3.9: Diagrama de tempo associada com o programa da figura 3.7
3.2 Especificação do paralelismo 
Figura 3.10: Grafo de precedência para o programa da figura 3.7
3.2 Especificação do paralelismo 
Muitas vezes são usados grafos de precedência para representar o paralelismo 
existente em um programa. No grafo de precedência, os nodos representam 
trechos de código e os arcos representam relações de precedência. 
Um arco no nodo X para o nodo Y representa que o código associado com Y 
somente poderá ser executado após o término do código associado com X. 
Vamos supor agora que o programador deseje que, necessariamente, o 
processo do filho 1 termine para então o processo filho 2 iniciar.
3.2 Especificação do paralelismo 
Figura 3.11: Programa do exemplo 3.7 alterado
3.2 Especificação do paralelismo 
Uma forma mais estruturada de especificar paralelismo em programas 
concorrentes é conseguida com o uso dos comandos Parbegin e Parend. 
Enquanto o par Begin-End delimita um conjunto de comandos que serão 
executados sequencialmente, o par Parbegin-Parend delimita um conjunto de 
comandos que serão executados em paralelo. 
O comando que segue ao Parend somente será executado quando todos os 
fluxos de controle criados na execução do Parbegin-Parend tiverem terminado.
3.2 Especificação do paralelismo 
Os comandos Parbegin-Parend definem uma nova estrutura de controle para a 
linguagem. Nos exemplos, a sintaxe da linguagem C foi estendida com a inclusão 
desse novo comando. 
Também é possível usar uma versão menos elegante para o comando Parbegin 
que, entretanto, mantém sua funcionalidade. 
Dessa vez, Parbegin aparece como uma função de biblioteca cujos parâmetros 
são os nomes das funções a serem disparadas em paralelo.
3.2 Especificação do paralelismo 
Figura 3.12: Exemplo contendo os comandos Parbegin e Parend
3.3 Problema da seção crítica 
Uma forma de implementar a passagem de dados de um processo para o outro 
são variáveis compartilhadas pelos processos envolvidos na comunicação. A 
passagem acontece quando um processo escreve em uma variável que será lida 
por outro processo. 
A quantidade exata de memória compartilhada entre os processos pode variar 
conforme o programa. Processos podem compartilhar todo o seu espaço de 
endereçamento, apenas um segmento de memória, algumas estruturas de 
dados ou algumas variáveis. 
O sistema operacional arranja para que os processos acessem as mesmas 
posições de memória.
3.3 Problema de seção crítica 
Figura 3.13: Compartilhamento de memória
3.3 Problema da seção crítica 
Não é possível eliminar as variáveis compartilhadas de um programa concorrente 
quando elas são o mecanismo de comunicação entre os processos. 
A solução está em controlar o acesso dos processos e suas variáveis 
compartilhadas, de modo a garantir que um processo não acesse uma estrutura 
de dados enquanto essa estiver sendo utilizada por outro processo. 
A parte do código de um processo que acessa uma estrutura de dados 
compartilhada é chamada de seção crítica.
3.3 Problema da seção crítica 
Uma solução para o problema da seção crítica estará correta quando apresentar 
as seguintes propriedades: 
● Existe exclusividade mútua entre os processos com referência na execução 
das respectivas seções críticas. 
● Quando um processo P deseja entrar na seção crítica e nenhum outro 
processo está executando a sua seção crítica, o processo P não é impedido de 
entrar. 
● Nenhum processo pode ter seu ingresso na seção crítica postergado 
indefinidamente, ou seja, ficar esperando para sempre. 
● Não depender da velocidade relativa da execução dos processos, nem da 
quantidade de processadores (cores) existentes.
3.4 Mecanismos básicos de exclusão mútua 
Tipicamente, uma solução para o problema da seção crítica tem a forma de um 
mecanismo que controla o acesso dos processos ao código da seção crítica. 
Através de primitivas específicas alocadas imediatamente antes (entrada) e 
imediatamente depois (saída) da seção crítica, esse mecanismo age de maneira a 
obter-se as quatro propriedades citadas anteriormente (ou, pelo menos, a 
maioria delas).
3.4.1 Soluções em software puro 
Dentro da categoria dos protocolos de software puro, os mais famosos são os 
algoritmos de Dekker e de Peterson. 
Nessas soluções os processos executam um determinado algoritmo na entrada 
e outro na saída da seção critica. 
Tais algoritmos não incluem nenhuma chamada ao sistema operacional, nem o 
emprego de instruções privilegiadas.
3.4.1 Soluções em software puro 
Figura 3.18: Protocolo de software puro: solução de Peterson
3.4.1 Soluções em software puro 
A variável flag é um array com duas posições, cada uma indica quando o 
respectivo processo deseja entrar na seção crítica (valor 1 indica "quero entrar"). 
A variável turn contem o número do processo com a preferência no momento. 
O processo P0 poderá entrar na seção crítica quando P1 não deseja entrar na 
seção crítica ou quando a preferência no momento é para P0. 
Embora o algoritmo apresentado funcione apenas para dois processos, ele pode 
ser extendido para o caso de muitos processos.
3.4.1 Soluções em software puro 
Soluções em software puro não são muito empregados na pratica por duas 
razões: 
1. são bastante complexas, o que dificulta a depuração dos problemas; 
2. apresentam a propriedade chamada busy-waiting, quando um processo 
aguarda em um laço a sinalização de um evento.
3.4.2 Desabilitação de interrupções 
Através desta solução simples, toda vez que um processo vai acessar variáveis 
compartilhadas antes ele desabilita interrupções. 
Dessa forma, ele pode acessar as variáveis com a certeza de que nenhum outro 
processo vai ganhar o processador, dado que as interrupções (timer, disco, etc.) 
que deflagram o escalonador. 
No final da seção crítica, ele torna a habilitar as interrupções. 
Esse esquema é efetivamente usado nas aplicações que executam em sistemas 
pequenos e dedicados, como sistemas embarcados (embedded systems).
3.4.2 Desabilitação de interrupções 
Desabilitar interrupções vai contra os mecanismos de proteção e não pode ser 
considerado um método genérico para resolver o problema da seção crítica. 
Essa é uma operação proibida para processos de usuário em sistemas de 
propósito geral já que são instruções que só podem ser executadas em modo 
privilegiado. 
Desabilitar interrupções também diminui a eficiência do sistema à medida que 
periféricos não são atendidos imediatamente durante as execuções de seções 
críticas (interrupções ficam pendentes e são atendidas somente após a seção 
crítica).
3.4.3 Spin-lock 
Essa solução é baseada em uma instrução de máquina chamada "test-and-set", 
embora uma instrução do tipo "swap" ou "compare on store" possa ser usada 
também. 
A seção crítica será protegida por uma variável que ocupará a posição da 
memória. Essa variável é normalmente chamada de lock (fechadura). 
Quando lock contém "0", a seção crítica está livre. Quando lock contém "1", ela 
está ocupada. A variável é inicializada com "0". 
Antes de entrar na seção crítica, um processo precisa "fechar a porta", 
colocando "1" em lock. Entretanto ele só pode fazer isso se "a porta estiver 
aberta".
3.5 Mutex 
O nome mutex é derivado de "mutual exclusion" (exclusão mútua). 
Uma variável mutex pode assumir apenas os valores livre e ocupado. 
A operação lock é usada pelo processo para solicitar acesso à seção crítica 
(entrada); 
A operação unlock permite ao processo informar que não deseja mais usar a 
seção crítica (saída).
3.5.1 Implementação de mutex 
No caso de computadores com um único processador, a solução mais comum é 
desabilitar interrupções. 
Para computadores com vários processadores, desabilitar interrupções não 
basta. 
Nesse caso, o spin-lock é usado, pois ele impede que um outro processo, 
executando em outro processador, execute a operação lock ou unlock sobre o 
mesmo mutex.
3.6 Semáforos 
Podemos sintetizar o funcionamento das operações P e V sobre um semáforo S 
da seguinte forma: 
P (S): 
S.valor = S.valor - 1; 
Se S.valor < 0 
Então bloqueia o processo, insere em S.fila 
V (S): 
S.valor = S.valor + 1; 
Se S.fila não está vazia 
Então retira processo P de S.fila, acorda P
3.6 Semáforos 
Para que semáforos funcionem corretamente, é essencial que as operações P e 
V sejam atômicas. Isso é, uma operação P ou V não pode ser interrompida no 
meio e outra operação sobre o mesmo semáforo iniciada. 
Semáforos tornam a proteção da seção crítica muito simples. 
Para cada estrutura de dados compartilhada, deve ser criado um semáforo S 
inicializado com o valor 1. 
Todo processo, antes de acessar essa estrutura, deve executar um P(S), ou seja, 
a operação P sobre o semáforo S associado com a estrutura de dados em 
questão. Ao sair da seção crítica, o processo executa V(S).
Bibliografia 
OLIVEIRA, R. S. de; CARISSIMI, A. da S. e TOSCANI, S.S. 
Sistemas Operacionais. Porto Alegre. Bookman, 2008.
4. Gerenciamento de Memória
4.1 Introdução 
Historicamente, a memória principal sempre foi vista como um recurso escasso e 
caro. 
Uma das maiores preocupações dos projetistas foi desenvolver Sistemas 
Operacionais que não ocupassem muito espaço de memória e, ao mesmo tempo, 
otimizassem a utilização dos recursos computacionais. 
Mesmo atualmente, com a redução de custo e consequente aumento da capacidade 
da memória principal, seu gerenciamento é um dos fatores mais importantes no 
projeto de Sistemas Operacionais. 
Enquanto nos sistemas monoprogramáveis a gerência da memória não é muito 
complexa, nos sistemas multiprogramáveis essa gerência se torna crítica, devido à 
necessidade de se maximizar o número de usuários e aplicações utilizando 
eficientemente o espaço da memória principal.
4.1.1 Funções básicas 
Em geral programas são armazenados em memórias secundárias, como 
discos ou fitas, por ser um meio não-volátil, abundante e de baixo custo. 
Como o processador somente executa instruções localizadas na memória 
principal, o Sistema Operacional deve sempre transferir programas da 
memória secundária para a memória principal antes deles serem executados. 
Como o tempo de acesso à memória secundária é muito superior ao tempo de 
acesso à memória principal, o Sistema Operacional deve buscar reduzir o 
número de operações de E/S à memória secundária, para evitar problemas de 
desempenho do sistema. 
A gerência de memória deve tentar manter na memória principal o maior 
número possível de processos residentes, permitindo maximizar o 
compartilhamento do processador e demais recursos computacionais.
4.1.1 Funções básicas 
Mesmo na ausência de espaço livre, o sistema deve permitir que novos processos sejam 
aceitos e executados. Isto é possível através da transferência temporária de processos 
residentes na memória principal para a memória secundária, liberando espaço para novos 
processos. Este mecanismo é conhecido como swapping. 
Outra preocupação na gerência de memória é permitir a execução de programas que 
sejam maiores que a memória física disponível, implementando técnicas como overlay 
e memória virtual. 
Em um ambiente de multiprogramação, o sistema operacional deve proteger as áreas de 
memória ocupadas por cada processo, além da área onde reside o próprio sistema. 
Caso um programa tente realizar algum acesso indevido à memória, o sistema de alguma 
forma deve impedí-lo. 
Apesar de a gerência de memória garantir a proteção de áreas da memória, mecanismos de 
compartilhamento devem ser oferecidos para que diferentes processos possam trocar 
dados de forma protegida.
4.2 Alocação de memória
4.2.1 Alocação Contígua Simples 
Foi implementada nos primeiros Sistemas Operacionais, porém ainda 
está presente em alguns sistemas monoprogramáveis. 
Nesse tipo de organização, a memória principal é subdividida em duas 
áreas: uma para o sistema operacional e outra para o programa do 
usuário. 
Dessa forma, o programador deve desenvolver suas aplicações, 
preocupado, apenas, em não ultrapassar o espaço de memória 
disponível, ou seja, a diferença entre o tamanho total da memória 
principal e área ocupada pelo Sistema Operacional.
4.2.1 Alocação Contígua Simples 
Alocação Contígua Simples
4.2.1 Alocação Contígua Simples 
Esquema em que o usuário tem controle sobre toda a 
memória principal, inclusive a área do Sistema Operacional. 
Implementa controle de proteção do sistema através de 
registrador que delimita a área do Sistema Operacional. 
Fácil implementação e código reduzido, porém não utiliza os 
recursos computacionais de forma eficiente, pois apenas um 
usuário/aplicação pode dispor deste recurso.
4.2.2 Técnica Overlay 
Na alocação contígua simples, todos os programas estão 
limitados ao tamanho da área de memória principal disponível 
para o usuário. 
Uma solução encontrada para o problema é dividir o programa 
em módulos, de forma que seja possível a execução 
independente de cada módulo, utilizando uma mesma área de 
memória. Essa técnica é chamada de overlay.
4.2.2 Técnica Overlay 
Técnica Overlay
4.2.2 Técnica Overlay 
A técnica de overlay utiliza uma área de memória comum, os os 
módulos “não-carregados” poderão compartilhar esta área de 
memória (área de overlay). 
Sempre que um módulo “não-carregado” for referenciado 
pelo módulo principal, o módulo será carregado da memória 
secundária para a área de overlay. 
No caso de uma referência a um módulo já carregado, a carga 
não será realizada.
4.2.2 Técnica Overlay 
A definição das áreas de overlay é função do programador, através de 
comandos específicos das linguagem de programação utilizada. 
O tamanho da área de overlay é estabelecido a partir do tamanho 
do maior módulo. 
Esta técnica tem a vantagem de permitir ao programador expandir os 
limites da memória principal, porém deve ser utilizada com cuidado, 
pois pode trazer sérios problemas de desempenho, devido a 
possibilidade de transferência excessiva dos módulos entre a memória 
principal e a secundária.
4.2.3 Alocação Contígua Particionada 
Os Sistemas Operacionais evoluíram no sentido de proporcionar 
melhor aproveitamento dos recursos disponíveis. 
Nos sistemas monoprogramáveis, o processador permace grande 
parte do tempo ocioso e a memória principal é subutilizada. 
Os sistemas multiprogramáveis já são muito mais eficientes no uso 
do processador, necessitando assim, que diversos programas estejam na 
memória principal ao mesmo tempo e que novas formas de gerência da 
memória sejam implementadas.
4.2.4 Alocação Contígua Particionada Fixa 
Nos primeiros sistemas multiprogramáveis, a memória era dividida 
em pedaços de tamanho fixo, chamados partições. 
O tamanho das partições, estabelecido na fase de inicialização do 
sistema, era definido em função do tamanho dos programas 
que executariam no ambiente. 
Sempre que fossem necessárias alterações do tamanho de uma 
partição, o sistema deveria ser reinicializado com a nova 
configuração.
4.2.4 Alocação Contígua Particionada Fixa 
Alocação Contígua Particionada Fixa (Estática) - Absoluta
4.2.4 Alocação Contígua Particionada Fixa 
Inicialmente, os programas só podiam ser carregados e executados em 
apenas uma partição específica, mesmo se outras estivessem disponíveis. 
Esta limitação se devia aos compiladores e montadores, que geravam 
apenas código absoluto. 
No exemplo acima, supondo que os programas A e B estivessem sendo 
executados, os programas C e E não poderiam ser processados na terceira 
partição, mesmo esta estando livre. 
A esse tipo de gerência chamou-se alocação particionada estática absoluta.
4.2.4 Alocação Contígua Particionada Fixa 
Com a evolução dos compiladores, montadores, ligadores e 
carregadores, o código gerado deixou de ser absoluto e passou a 
ser realocável. 
No código realocável, todas as referências a endereços no 
programa são relativas ao início do código e não a 
endereços físicos de memória. 
Desta forma, os programas puderam ser executados a partir de 
qualquer partição.
4.2.4 Alocação Contígua Particionada Fixa 
Alocação Contígua Particionada Fixa (Estática) - Realocável
4.2.4 Alocação Contígua Particionada Fixa 
Supondo que na partição 1 esteja o programa C, na partição 2 o 
programa A e na partição 3 o programa B. 
Caso os programas A e B terminassem, o programa E poderia ser 
executado tanto na partição 2 quanto na partição 3. 
Para manter o controle sobre as partições alocadas, a 
gerência de memória mantém uma tabela com o endereço inicial 
de cada partição, seu tamanho, e se está em uso ou não.
4.2.4 Alocação Contígua Particionada Fixa 
Tabela de Alocação de Partições
4.2.4 Alocação Contígua Particionada Fixa 
A esse tipo de gerência chamou-se alocação particionada estática 
relocável. 
Neste esquema de memória, a proteção baseia-se em dois 
registradores, que indicam os limites (inferior e superior) da 
partição onde o programa está sendo executado.
4.2.4 Alocação Contígua Particionada Fixa 
Proteção na Alocação Particionada
4.2.4 Alocação Contígua Particionada Fixa 
Tanto nos sistemas de alocação absoluta quanto nos de 
alocação realocável, os programas, normalmente, não 
preenchem totalmente as partições onde são carregados, 
deixando área de memória livre. 
Este problema é conhecido como fragmentação interna. 
Exemplo de implementação: OS/MFT (Multiprogramming with 
Fixed Number of Tasks) da IBM
4.2.5 Alocação Contígua Particionada Dinâmica 
Na alocação particionada dinâmica ou variável, foi eliminado o conceito de 
partições de tamanho fixo. 
Nesse esquema, cada programa utilizaria o espaço necessário, tornando essa 
área sua partição. 
Como cada programa utiliza apenas o espaço que necessita, o programa de 
fragmentação interna não ocorre. 
Um outro problema começará a ocorrer, conhecido como fragmentação externa. 
Ele ocorre quando os programas forem terminando e deixando espaços 
cada vez menores na memória, não permitindo o ingresso de novos programas.
4.2.5 Alocação Contígua Particionada Dinâmica 
Alocação Contígua Particionada Dinâmica
4.2.5 Alocação Contígua Particionada Dinâmica 
Existem duas soluções para este problema. 
O primeiro método indica que, conforme os programas 
terminem, apenas os espaços livres adjacentes sejam reunidos, 
produzindo áreas livres de tamanho maior.
4.2.5 Alocação Contígua Particionada Dinâmica 
Primeira solução para fragmentação interna
4.2.5 Alocação Contígua Particionada Dinâmica 
A segunda solução envolve a relocação de todas as partições 
ocupadas, eliminando todos os espaços entre elas e criando 
uma única área livre contígua. 
Para que esta solução possa ser implementada, é necessário que o 
sistema tenha a capacidade de mover os diversos programas na 
memória principal, ou seja, realizar a relocação dinâmica.
4.2.5 Alocação Contígua Particionada Dinâmica 
Segunda solução para fragmentação interna
4.2.5 Alocação Contígua Particionada Dinâmica 
Esta técnica de gerenciamento é conhecida como alocação 
particionada dinâmica com relocação. 
Reduz em muito o problema da fragmentação, porém aumenta a 
complexidade do algoritmo e o consumo de recursos do sistema 
(processador e área de disco). 
Exemplo de implementação: OS/MVT (Multiprogramming with 
a Variable Number os Tasks) da IBM.
4.2.6 Estratégias de Alocação de Partição 
O Sistemas Operacionais implementam, basicamente, três 
estratégias para determinar em qual área livre um programa 
será carregado para execução. 
A melhor estratégia depende de uma série de fatores, como 
o tamanho dos programas a serem processados. Independente 
do algoritmo utilizado, o sistema possui uma lista das áreas livres, 
com o endereço e o tamanho de cada área.
4.2.6 Estratégias de Alocação de Partição 
Estratégias de Alocação de Partição
4.2.6 Estratégias de Alocação de Partição 
Qual partição livre alocar a um processo que pede por um tamanho X ? 
● FIRST-FIT: a primeira partição livre onde caibam X bytes é escolhida; 
○ A procura pode começar sempre no início da lista, ou a partir do último 
bloco alocado (“next-fit”). 
● BEST-FIT: a partição livre de tamanho mais parecido com X bytes é 
escolhida (sendo igual ou maior do que X); 
○ Pode se aproveitar da ordenação da lista de área ivres. 
○ Pode aumentar o problema de fragmentação. 
● WORST-FIT: a maior a partição livre é escolhida; 
○ Diminui o problema de fragmentação, pois deixa espaços livres maiores.
4.2.6 Estratégias de Alocação de Partição 
Exemplo de Uso das Estratégias de Alocação de Partição
Bibliografia 
TANEMBAUM, Andrew S. Sistemas Operacionais Modernos. 2a ed. São 
Paulo: Pearson, 2003.
5. Gerenciamento de 
Memória Virtual
5.1 Introdução 
Memória Virtual é uma ténica poderosa e sofisticada de gerência de memória, onde as memórias principal 
e secudária são combinadas, dando ao usuário a ilusão de existir uma memória muito maior que a 
capacidade real da memória principal. 
O conceito desta técnica fundamenta-se em não vincular o endereçamento feito pelo programa aos 
endereços físicos da memória principal. Desta forma, programas e suas estruturas de dados deixam de 
estar limitados ao tamanho da memória física disponível, pois podem possuir endereços associados à 
memória secundária. 
Outra vantagem é permitir um número maior de processos compartilhando a memória principal, 
utilizando de forma mais eficiente o processador. Também possibilita a minimização do problema da 
fragmentação da memória principal. 
A primeira implementação foi realizada no início da década de 1960, no sistema Atlas, desenvolvido na 
Universidade de Manchester (Kilburn, 1962). Posteriormente, a IBM introduziria este conceito 
comercialmente na família System/370 em 1972. Atualmente a maioria dos sistemas operacionais 
utilizam-se desta técnica de gerenciamento, com exceção de alguns sistemas de supercomputadores.
5.1 Introdução 
Existe um forte relacionamento entre a gerência de memória virtual e a 
arquitetura de hardware do sistema computacional. Por motivos de desempenho, 
é comum que algumas funções da gerência de memória virtual sejam 
implementadas diretamente no hardware. 
Além disso, o código do sistema operacional deve levar em consideração várias 
características específicas da arquitetura, especialmente o esquema de 
endereçamento do processador. 
A gerência de memória virtual, também conhecida como gerência de alocação 
não-contígua, aborda três técnicas que permitem sua implementação: paginação, 
segmentação e segmentação com paginação.
5.1.1 Espaço de endereçamento virtual 
O conceito de memória virtual se aproxima muito da idéia de um vetor, existente 
nas linguagens de alto nível. Quando um programa faz referência a um elemento 
do vetor, não há preocupação em saber a posição de memória daquele dado. O 
compilador encarrega-se de gerar instruções que implementam esse mecanismo, 
tornando-o totalmente transparente ao programador. 
No caso da memória virtual, a abstração ocorre em relação aos endereços dos 
programas e dados. Um programa no ambiente de memória virtual não faz 
referência a endereços físicos de memória (endereços reais), mas apenas a 
endereços virtuais. O momento da execução, o endereço virtual referenciado é 
traduzido para um endereço físico, pois o processador manipula apenas posições 
da memória principal. O mecanismo de tradução destes endereços é denominado 
como mapeamento.
5.1.1 Espaço de endereçamento virtual 
Espaços de endereçamento virtual x real
5.1.1 Espaço de endereçamento virtual 
Programas podem fazer referência a endereços virtuais que estejam fora dos limites da 
memória principal, não há mais a limitação do tamanho da memória física disponível. 
A memória secundária é utilizada como extensão da memória principal. 
Quando um programa é executado, apenas parte do seu código fica residente na memória 
principal, permanecendo o restante na memória secundária até ser referenciado. 
Possibilita aumentar o compartilhamento da memória principal entre muito processos. 
No desenvolvimento das aplicações, os programadores não necessitam preocupar-se dos 
endereços virtuais, uma vez que os compiladores e ligadores (linkers) se encarregam desta 
tarefa.
5.1.1 Espaço de endereçamento virtual 
Espaço de endereçamento virtual
5.1.2 Mapeamento 
O processador apenas executa instruções e referencia dados residentes no espaço de endereçamento 
real; portanto, deve existir um mecanismo que transforme os endereços virtuais em endereços reais. 
Esse mecanismo, conhecido por mapeamento, permite traduzir um endereço localizado no espaço 
virtual para um associado no espaço real. A consequencia deste mapeamento é que um programa não 
necessita estar necessariamente alocado em endereços contíguos na memória principal para ser 
executado. 
Nos sistemas modernos, a tarefa de tradução de endereços virtuais é realizada pelo hardware 
juntamente com o sistema operacional, de forma a não comprometer seu desempenho e torná-lo 
totalmente transparente a usuários e aplicações. O dispositivo de hardware responsável por essa 
tradução é conhecido como Unidade de Gerência de Memória (Memory Management Unit – MMU), 
sendo acionado sempre que se faz referência a um endereço virtual. Depois de traduzido, o endereço 
real pode ser utilizado pelo processador para o acesso à memória principal. 
Como cada processo tem seu próprio endereçamento virtual, o mecanismo de tradução encarrega-se 
de manter tabelas de mapeamento exclusivas para cada processo.
5.1.2 Mapeamento 
Tabela de Mapeamento
5.1.2 Mapeamento 
A tabela de mapeamento é uma estrutura de dados existente para cada 
processo. 
A troca de tabelas (de um processo para outro) é realizada através de 
um registrador, que indica a posição inicial da tabela corrente. 
Toda a vez que há uma mudança de contexto, o registrador é atualizado 
com o endereço da nova tabela. 
As tabelas mapeiam blocos de dados, cujo o tamanho determina o 
número de entradas existentes nas tabelas de mapeamento.
5.1.2 Mapeamento
5.1.3 Alocação de Memória Virtual por Paginação 
Técnica de gerência de memória onde o espaço de endereçamento virtual e o 
espaço de endereçamento real são divididos em blocos de mesmo tamanho 
chamados páginas. As páginas no espaço virtual são denominadas páginas 
virtuais, enquanto que as páginas do espaço real são chamadas de páginas reais 
ou frames. 
Todo o mapeamento de endereço virtual em real é realizado através de tabelas 
de páginas. Cada processo possui sua própria tabela de páginas e cada página 
virtual do processo possui uma entrada na tabela, com informações de 
mapeamento que permitem ao sistema localizar a página real correspondente.
5.1.3 Alocação de Memória Virtual por Paginação 
Alocação de Memória Virtual por Paginação
5.1.3 Alocação de Memória Virtual por Paginação 
Quando um programa é executado, páginas virtuais são transferidas da memória 
secundária para a memória principal e colocadas nos frames. 
Nesta técnica, o endereço virtual é formado pelo número da página virtual (NPV) e por um 
deslocamento. O endereço físico é obtido combinando-se o endereço do frame, localizado 
na tabela de páginas, com o deslocamento, contido no endereço virtual. 
Além da informação sobre a localização da página virtual, a ETP possui outras informações, 
como o bit de validade (valid bit) que indica se uma página está carregada na memória 
principal. Se o bit for 0 (zero), indica que não a página não está carregada, mas se o valor for 
1, a página está carregada na memória principal. 
Caso a página referenciada não esteja na memória principal, dizemos que ocorreu um page 
fault. Neste caso, o sistema transfere a página da memória secundária para a memória 
principal, realizando uma operação de E/S conhecida como page in ou paginação.
5.1.3 Alocação de Memória Virtual por Paginação 
Tradução do Endereço Virtual
5.1.4 Proteção e Compartilhamento de Memória 
Em qualquer sistema multiprogramável, onde diversas aplicações compartilham 
a memória principal, devem existir mecanismos para preservar as áreas de 
memória do sistema operacional e dos diversos processos dos usuários. 
Um primeiro nível de proteção é inerente ao próprio mecanismo de memória 
virtual por paginação, onde cada processo tem a sua própria tabela de 
mapeamento e a tradução dos endereços é realizada pelo sistema. Desta forma 
um processo não pode acessar as áreas de memória de outros processos, a 
menos que haja compartilhamento explícito de páginas entre os processos. 
A proteção de acesso é realizada individualmente em cada página da memória 
principal, utilizando-se as entradas das tabelas de mapeamento onde alguns bits 
especificam os acessos permitidos.
5.1.4 Proteção e Compartilhamento de Memória
5.1.4 Proteção e Compartilhamento de Memória 
● De forma resumida há dois tipos de acessos básicos realizado em uma 
página: leitura e gravação. É possível a combinação destes acessos, 
produzindo um mecanismo simples e eficiente. 
Mecanismo de Proteção
5.1.5 Alocação de Memória Virtual por Segmentação 
É a técnica de gerência de memória onde o espaço de endereçamento virtual é 
dividido em blocos de tamanhos diferentes chamados segmentos. Na técnica de 
segmentação, um programa é dividido logicamente em sub-rotinas e estruturas 
de dados, que são alocadas em segmentos na memória principal. 
Há uma relação entre a lógica do programa e sua alocação na memória principal. 
Normalmente a definição dos segmentos é realizada pelo compilador, a partir do 
código fonte do programa, e cada segmento pode representar um procedimento, 
função, vetor ou pilha. 
O espaço de endereçamento virtual de um processo possui um número máximo 
de segmentos que podem existir, onde cada segmento pode variar de tamanho 
dentro de um limite. O tamanho do segmento pode ser alterado durante a 
execução do programa.
5.1.5 Alocação de Memória Virtual por Segmentação 
Segmentação
5.1.6 Alocação de Memória Virtual por Segmentação 
com Paginação 
É a técnica de gerência de memória onde o espaço de endereçamento é dividido em segmentos e, por sua 
vez, cada segmento dividido em páginas. Esse esquema de gerência de memória tem o objetivo de 
oferecer as vantagens tanto da técnica de paginação quanto da técnica de segmentação. 
Nessa técnica, um endereço virtual é formado pelo número do segmento virtual (NSV), um número de 
página virtual (NPV) e um deslocamento. 
Através no NSV, obtém-se uma entrada na tabela de segmentos, que contém informações da tabela de 
páginas do segmento. O NPV identifica unicamente a página virtual que contém o endereço, funcionando 
como um índice na tabela de páginas. O deslocamento indica a posição do endereço virtual em relação ao 
início da página na qual se encontra. O endereço físico é obtido, então, combinando-se o endereço do 
frame, localizado na tabela de páginas, com o deslocamento, contido no endereço virtual. 
Na visão do programador, sua aplicação continua sendo mapeada em segmentos de tamanhos diferentes, 
em função das sub-rotinas e estruturas de dados definidas no programa. Por outro lado, o sistema trata 
cada segmento como um conjunto de páginas de mesmo tamanho, mapeadas por uma tabela de páginas 
associadas ao segmento. Dessa forma, um segmento não precisa estar contíguo na memória principal, 
eliminando o problema da fragmentação externa encontrado na segmentação pura.
5.1.6 Alocação de Memória Virtual por Segmentação 
com Paginação 
Segmentação com Paginação
5.1.7 Swapping em Memória 
A técnica de swapping permite aumentar o número de processos que compartilham a 
memória principal e, consequentemente, o grau de multiprogramação do sistema. 
Quando existem novos processos para serem executados e não há memória principal 
livre suficiente para alocação, o sistema utiliza o swapping, selecionando um ou mais 
processos para saírem da memória e oferecer espaço para novos processos. Depois de 
escolhidos, o sistema retira os processos da memória principal para a memória 
secundária (swap out), onde as páginas ou segmentos são gravados em um arquivo de 
swap (swap file). 
Com os processos salvos na memória secundária, os frames ou segmentos alocados 
são liberados para novos processos. Porteriormente, os processos que forem retirados 
da memória devem retornar para a memória principal (swap in) para serem novamente 
executados.
5.1.7 Swapping em Memória 
Há várias políticas que podem ser aplicadas na escolha dos processos que devem ser 
retirados da memória principal. Todas elas buscam os processos com menor chance de 
serem executados em um futuro próximo, sendo que a maioria dos critérios de 
escolha baseiam-se no estado do processo e na sua prioridade. 
O swapping com base em estado seleciona, inicialmente, os processos com estado em 
espera; porém se estes não forem suficientes ele também selecionará os em estado 
de pronto com menor prioridade. 
O arquivo de swap é compartilhado por todos os processos que estão em execução. 
Cada processo tem uma área reservada no arquivo que é liberada quando o processo é 
eliminado. Em alguns sistemas, o arquivo de swap é, na verdade, uma área em disco 
reservada exclusivamente para esta função.
5.1.8 Trashing 
Pode ser definido como sendo a excessiva transferência de páginas/segmentos entre a 
memória principal e a memória secundária. Esse problema está presente em sistemas que 
implementam tanto paginação como segmentação. 
Na memória virtual por paginação, o thrashing ocorre em dois níveis: no do próprio 
processo e no do sistema. No nível do processo, a excessiva paginação ocorre devido ao 
elevado número de page faults gerado pelo programa em execução. Esse problema faz com 
que o processo passe mais tempo esperando por páginas que realmente sendo executado. 
No nível de sistema ocorre quando existem mais processos competindo por memória 
principal que espaço disponível. Neste caso, o ideal é reduzir o número de páginas de cada 
processo na memória, poré isto leva ao thrashing do processo. Caso a redução não seja 
suficiente, o sistema iniciará o swapping. Se este mecanismos for ao extremo, o sistema 
passará mais tempo realizando swappings que atendendo aos processos.
5.1.8 Trashing 
Em sistema que implementam segmentação, o thrashing também ocorre em dois 
níveis. No nível do processo, a transferência excessiva de segmentos é devida à 
modularização extrema do programa. E no nível do sistema é semelhante ao da 
paginação, com a ocorrência de swapping de processos para liberar memória para 
os demais. 
Independente das soluções apresentadas, se existirem mais processos para serem 
executados que memória real disponível, a única solução é a expansão da 
memória principal. 
É importante ressaltar que este problema não ocorre apenas em sistema que 
implementam memória virtual, mas também em sistemas com outros mecanismos 
de gerência de memória.
Bibliografia 
TANEMBAUM, Andrew S. Sistemas Operacionais Modernos. 2a ed. São 
Paulo: Pearson, 2003.
6. Gerenciamento 
de Dispositivos
6.1 Fundamentos 
Uma parte bastante importante dentro dos Sistemas 
Operacionais é a dos mecanismos de Entradas e Saídas, 
através do qual o sistema se comunica com o mundo 
externo. 
Este nível é composto por processos servidores de E/S 
(gerentes de dispositivos e drivers) que também são 
processos do S.O. e também competem pelos seus recursos.
6.1 Fundamentos 
Entrada é toda instrução de envio de dados ao mundo exterior e 
Saída é toda instrução de recepção de dados dele. Essas 
instruções, em geral compreendem duas etapas: 
1. Saída: 
○ comandos de ação do dispositivo. 
○ comandos de atribuição de dados para a operação. 
2. Entrada: 
○ comandos de indicação de endereços dos dados. 
○ comandos de verificação do estado do dispositivo.
6.1 Fundamentos 
Portanto as instruções de E/S são sempre do tipo: 
○ Sai comando; 
○ Sai dados; 
○ Entra dados; e 
○ Entra Estado do Dispositivo. 
Toda operação do tipo E/S pode ser subdividida no tempo em 3 etapas distintas: 
1. Início da E/S 
2. Transferencia de dados 
3. Finalização da operação 
Em geral, existe um sistema de 'RETRAY' para o caso de finalizações sem 
sucesso.
6.2 Tipos de E/S 
E/S com Polling (Interrogação): Implementa certo paralelismo 
entre a UCP e os Dispositivos de E/S. 
● O programa após iniciar uma operação de E/S num 
dispositivo, continua executando outras tarefas (por 
exemplo, outra operação de E/S num outro dispositivo) e 
periodicamente testa o estado do dispositivo disparado para 
verificar se ele já completou a operação. 
● É programada pelo usuário, o programa fica dependente dos 
aspectos físicos, além de não perder o controle da UCP. Além 
disso, o programa depende as características do dispositivos e 
perde a portabilidade.
6.2 Tipos de E/S 
E/S Assíncronas Com Interrupções: O programa inicia a 
operação de E/S passando comando ao dispositivo e continua 
outras tarefas em paralelo, até que o dispositivo encerre a 
operação, gerando um sinal de interrupção para a UCP para que a 
finalização da operação seja executada.
6.2 Tipos de E/S 
E/S Por Acesso Direto A Memória (DMA): É um mecanismo de E/S assíncrona 
não programada onde um dispositivo controlador de acessos a memória do 
sistema promove as operações de E/S diretamente, independente da 
participação da UCP, disputando com ela as vias de dados e endereços, e 
sinalização só no final da operação. 
● Note que num mecanismo de interrupções sem DMA a cada operação, o 
dispositivo gera um sinal para a UCP a fim de completar a operação. 
● No sistema de DMA, a UCP comanda um acesso passando as instruções e o 
endereço na memória do dado a ser transferido e o Controlador de DMA 
faz toda a operação e somente avisa a UCP de sua execução, sem 
necessidade de sua intervenção.
6.2 Tipos de E/S 
No uso de DMA, usa-se também a E/S programada para transferências de 
comandos e endereços ao Controlador. Informações para o Controlador: 
● End. Inicial do bloco de dados na memória onde se dará a operação. 
● Sentido da transferência de dados (leitura ou escrita). 
● Número de células de memória a serem transferidas. 
OBS.: A memória só tem um porto de acesso (ponto de entrada) e um 
mecanismo de arbitração incorporado ao hardware define que tem direito a 
acessar, de acordo com sua prioridade. A prioridade maior é dada aos 
Controladores de ADM e depois a UCP pois sua velocidade é muito maior 
que a dos dispositivos. Este mecanismo é chamado Roubo de Ciclo ('cicle 
stealing').
6.2 Tipos de E/S 
E/S por CANAIS 
Característico de sistemas grandes, um Canal é um processador dedicado as 
funções de E/S. Pode executar Programas de canal armazenados em certos 
endereços da memória que a UCP passa como parâmetro ao processador de 
canal. 
● Nos IBM: Canais de E/S. 
● Nos CDC cyber: PPU (Periferal Processor Unit) 
Canais podem ser multiplexados por um mesmo processador de canal, de modo 
a ter-se em andamento várias entradas ou saídas ocorrendo em paralelo, 
controladas pelo mesmo processador de canal.
6.2 Tipos de E/S 
BUFFERS 
No histórico dos S.O., vimos que a velocidade de processamento dependia no 
início da velocidade dos periféricos, pois não havia até então paralelismo entre 
eles e a UCP. 
Além dos avanços no Hardware e nas formas de E/S, os sistemas mais recentes 
implementam formas de E/S que fazem uso de BUFFERS que são meios de 
armazenamento intermediários utilizados para suavizar as diferenças de 
velocidade de produção e consumo de dados entre a UCP e os Dispositivos. 
A estratégia de bufferização está baseada nos comandos de Sincronização entre 
processos Produtor/consumidor, tratado no capítulo sobre sincronismo, através 
das primitivas Wait e Signal do núcleo.
6.3 Camadas 
A gerência de dispositivos é parte do S.O. responsável por 
ocultar das aplicações os detalhes de controle e operação 
dos diversos dispositivos conectados ao sistema. 
A própria gerência de dispositivos é normalmente 
implementada em diversas camadas, de forma a 
proporcionar uma melhor generalização das operações de 
controle frente a constante evolução e mudança da 
tecnologia de implementação do hardware dos 
dispositivos.
6.3 Camadas 
● Assim, a maioria dos S.O.s implementa a gerência de 
dispositivos em um esquema parecido com o abaixo 
representado:
6.3 Camadas 
Biblioteca de E/S 
Normalmente, as linguagens oferecem comando para manipular 
os recursos de E/S, que são o primeiro nível de interação do 
aplicativo com a gerência de E/S. 
Esses comandos são independentes até mesmo do S.O. 
Por exemplo, o usuário cria um arquivo em qualquer linguagem 
através de um comando da própria linguagem que não o obriga a 
saber nada sobre como será a formatação física do arquivo no 
disco.
6.3 Camadas 
Biblioteca de E/S 
O compilador da linguagem, por sua vez, traduz esses comandos em comando 
Chamadas de Sistema, que são os comandos oferecidos pela camada mais de 
cima da gerência de dispositivos e que, no desenho acima, chamamos biblioteca 
de E/S. Cada System call da biblioteca possui parâmetros que são passados pelo 
compilador da linguagem, naturalmente ainda independentemente da 
implementação física, e resolvidos na fase de link do programa do usuário. 
Além de esconder características de implementação, as Chamadas de Sistema 
têm por objetivo oferecer um nível onde sejam implementadas rotinas que 
afinal são comuns a várias linguagens e a diferentes aplicativos e que, portanto, 
não precisam ser duplicadas nos diferentes aplicativos ou linguagens.
6.3 Camadas 
Sistemas de E/S 
É a camada imediatamente abaixo na estrutura da Gerência de E/S e tem os 
seguintes objetivos: 
● Realizar operações comuns a dispositivos distintos, sem levar em 
consideração aspectos específicos do dispositivo 
● Fazer o mapeamento entre dispositivos lógicos e seus respectivos drivers 
de dispositivos físicos 
● Uniformizar unidades de informação (blocos, registros, bytes, etc.) 
● Gerenciar a ocorrência de alguns tipos de erros 
● Controlar o compartilhamento de recursos, impondo os sincronismos que 
se fizerem necessários 
● Controlar as prerrogativas de acesso dos usuários aos dispositivos 
● Controlar a bufferização das informações com o objetivo de acelerar as 
operações de E/S.
6.3 Camadas 
Drivers de Software 
Os drivers de software, device drivers ou simplesmente drivers, manipulam um 
só dispositivo ou, no máximo, uma família de dispositivos. 
Normalmente os drivers são feitos em Assembly pelo próprio fabricante do 
dispositivo e são fornecidos gratuitamente quando se compra o Hardware (ou 
são disponibilizados da internet, por exemplo). 
Suas funções são: 
● Receber comandos genéricos e traduzí-los para comandos específicos do 
dispositivo 
● Manipular os registradores e demais elementos de hardware específicos do 
controlador
6.3 Camadas 
Drivers de Software 
Mapear unidades de um nível superior (como por exemplo 
blocos) em unidades físicas do dispositivo (como por 
exemplo, disco, trilhas, setores, etc.) 
Gerar e manipular interrupções de operações feitas por 
hardware dedicado (fim de transferência de um bloco de 
dados ou erro de transferência de dados, por exemplo).
6.3 Camadas 
Drivers de Software
6.3 Camadas 
Controladoras 
São placas de hardware que possuem registradores, memória local e as 
vezes processadores dedicados a manipular um determinado 
dispositivo. 
Em geral bufferizam a informação recebida ou enviada ao dispositivo 
por um barramento dedicado ou algum outro canal de comunicação e 
transferem os dados para a memória principal geralmente através de 
DMA. 
Assim, a CPU fica livre para realizar outras operações enquanto está se 
realizando a transferência de dados do/para o dispositivo.
6.3 Camadas 
Controladoras 
Alguns padrões de controladoras utilizados atualmente são: 
● IDE interface controladora de discos magnéticos e óticos mais utilizada nos 
computadores pessoais. Possui um padrão mais antigo (PIO) e um mais 
recente (ULTRA DMA) 
● SCSI (Small Computer System Interface) – define padrões de Hardware e 
software que permitem conectar diferentes dispositivos como discos 
magnéticos, óticos, scanners, unidades de fita, etc. 
● USB – interface de uso geral com protocolo de rede que permite conectar 
virtualmente todos os dispositivos de uma máquina (inclusive teclado e 
mouse) e que começa a se configurar como o provavel padrão de futuro.
6.3 Camadas 
Dispositivos 
São os equipamentos propriamente ditos, como impressoras, discos, fitas, 
teclados, scanners, vídeos, registradores gráficos, etc. 
Podem ser divididos em estruturados e não estruturados. Estruturados são os 
que transferem informações em blocos (estruturas) de tamanho fixo. A 
transferência pode ser direta, como no caso dos discos onde se acessa 
diretamente o endereço de um bloco ou seqüencial, como no caso das fitas, em 
que é preciso percorrer seqüencialmente o meio de armazenamento. 
Os não estruturados são os dispositivos em que os dados fluem em lotes de 
tamanho indefinido, ou mesmo um a um, como é o caso dos teclados, mouse ou 
impressoras.
Bibliografia 
TANEMBAUM, Andrew S. Sistemas Operacionais Modernos. 2a ed. São 
Paulo: Pearson, 2003.

Mais conteúdo relacionado

Mais procurados

Sistemas Distribuídos - Computação Distribuída e Paralela
Sistemas Distribuídos - Computação Distribuída e ParalelaSistemas Distribuídos - Computação Distribuída e Paralela
Sistemas Distribuídos - Computação Distribuída e Paralela
Adriano Teixeira de Souza
 

Mais procurados (20)

Introdução ao desenvolvimento de páginas web estáticas
Introdução ao desenvolvimento de páginas web estáticasIntrodução ao desenvolvimento de páginas web estáticas
Introdução ao desenvolvimento de páginas web estáticas
 
Sistemas Operativos (Operating Systems)
Sistemas Operativos (Operating Systems)Sistemas Operativos (Operating Systems)
Sistemas Operativos (Operating Systems)
 
SO-04 Escalonamento de Processos
SO-04 Escalonamento de ProcessosSO-04 Escalonamento de Processos
SO-04 Escalonamento de Processos
 
Sistemas Operacionais - Aula 9 (Gerencia do Processador)
Sistemas Operacionais - Aula 9 (Gerencia do Processador)Sistemas Operacionais - Aula 9 (Gerencia do Processador)
Sistemas Operacionais - Aula 9 (Gerencia do Processador)
 
Sistemas Operacionais - Aula 05 (Concorrência)
Sistemas Operacionais - Aula 05 (Concorrência)Sistemas Operacionais - Aula 05 (Concorrência)
Sistemas Operacionais - Aula 05 (Concorrência)
 
Banco de dados exercícios resolvidos
Banco de dados exercícios resolvidosBanco de dados exercícios resolvidos
Banco de dados exercícios resolvidos
 
Montagem manutenção de computadores
Montagem manutenção de computadoresMontagem manutenção de computadores
Montagem manutenção de computadores
 
Visão Geral: Estruturas do Sistema Operacional
Visão Geral: Estruturas do Sistema OperacionalVisão Geral: Estruturas do Sistema Operacional
Visão Geral: Estruturas do Sistema Operacional
 
Manutenção de Computadores - Aula 1
Manutenção de Computadores - Aula 1Manutenção de Computadores - Aula 1
Manutenção de Computadores - Aula 1
 
Gerenciamento de Arquivos Nos Sistemas Operacionais
Gerenciamento de Arquivos Nos Sistemas OperacionaisGerenciamento de Arquivos Nos Sistemas Operacionais
Gerenciamento de Arquivos Nos Sistemas Operacionais
 
Aula 4 banco de dados
Aula 4   banco de dados Aula 4   banco de dados
Aula 4 banco de dados
 
Sistema Operacional Android
Sistema Operacional AndroidSistema Operacional Android
Sistema Operacional Android
 
Linux
LinuxLinux
Linux
 
Introdução ao Linux
Introdução ao LinuxIntrodução ao Linux
Introdução ao Linux
 
Sistemas Distribuídos - Computação Distribuída e Paralela
Sistemas Distribuídos - Computação Distribuída e ParalelaSistemas Distribuídos - Computação Distribuída e Paralela
Sistemas Distribuídos - Computação Distribuída e Paralela
 
Sistema operacional introdução
Sistema operacional introduçãoSistema operacional introdução
Sistema operacional introdução
 
Modelos de Banco de dados e SGBDS
Modelos de Banco de dados e SGBDSModelos de Banco de dados e SGBDS
Modelos de Banco de dados e SGBDS
 
Aula 01 - Sistemas Operacionais - Windows 10
Aula 01 - Sistemas Operacionais - Windows 10Aula 01 - Sistemas Operacionais - Windows 10
Aula 01 - Sistemas Operacionais - Windows 10
 
ApresentaçãO2 Sistema Operacional
ApresentaçãO2  Sistema OperacionalApresentaçãO2  Sistema Operacional
ApresentaçãO2 Sistema Operacional
 
Aula I - Introdução ao Windows
Aula I - Introdução ao WindowsAula I - Introdução ao Windows
Aula I - Introdução ao Windows
 

Destaque

Sistemas Operacionais - Introducao
Sistemas Operacionais - IntroducaoSistemas Operacionais - Introducao
Sistemas Operacionais - Introducao
Luiz Arthur
 
Sistemas operacionais lista de exercicios
Sistemas operacionais lista de exerciciosSistemas operacionais lista de exercicios
Sistemas operacionais lista de exercicios
Carlos Melo
 
Convercao Binario e hexadecimal
Convercao Binario e hexadecimalConvercao Binario e hexadecimal
Convercao Binario e hexadecimal
Celso Corazza
 
Sistema operacional
Sistema operacionalSistema operacional
Sistema operacional
Michael Soto
 
Seminário 1º Tema parte III - Estados de processos e escalonamento de processos
Seminário 1º Tema parte III - Estados de processos e escalonamento de processosSeminário 1º Tema parte III - Estados de processos e escalonamento de processos
Seminário 1º Tema parte III - Estados de processos e escalonamento de processos
Robson Ferreira
 

Destaque (20)

Gerência de processos
Gerência de processosGerência de processos
Gerência de processos
 
Gerência de Armazenamento: Sistemas de Armazenamento em Massa
Gerência de Armazenamento: Sistemas de Armazenamento em MassaGerência de Armazenamento: Sistemas de Armazenamento em Massa
Gerência de Armazenamento: Sistemas de Armazenamento em Massa
 
Sistemas operacionais
Sistemas operacionaisSistemas operacionais
Sistemas operacionais
 
Capítulo 5 Sistemas Operacionais Modernos
Capítulo 5 Sistemas Operacionais ModernosCapítulo 5 Sistemas Operacionais Modernos
Capítulo 5 Sistemas Operacionais Modernos
 
Capítulo 10 Sistemas Operacionais Modernos
Capítulo 10 Sistemas Operacionais ModernosCapítulo 10 Sistemas Operacionais Modernos
Capítulo 10 Sistemas Operacionais Modernos
 
Sistemas Operacionais - Introducao
Sistemas Operacionais - IntroducaoSistemas Operacionais - Introducao
Sistemas Operacionais - Introducao
 
Fundamentos de Sistemas Operacionais - Aula 1 - Introdução à disciplina
Fundamentos de Sistemas Operacionais - Aula 1 - Introdução à disciplinaFundamentos de Sistemas Operacionais - Aula 1 - Introdução à disciplina
Fundamentos de Sistemas Operacionais - Aula 1 - Introdução à disciplina
 
Sistemas Operacionais
Sistemas OperacionaisSistemas Operacionais
Sistemas Operacionais
 
Sistemas operacionais
Sistemas operacionaisSistemas operacionais
Sistemas operacionais
 
Aula 3
Aula 3Aula 3
Aula 3
 
Tutorial de Uppaal
Tutorial de UppaalTutorial de Uppaal
Tutorial de Uppaal
 
Historia dos sistemas operacionais
Historia dos sistemas operacionaisHistoria dos sistemas operacionais
Historia dos sistemas operacionais
 
Pseudoparalelismo
PseudoparalelismoPseudoparalelismo
Pseudoparalelismo
 
Notas sobre Sistemas Operacionais
Notas sobre Sistemas Operacionais Notas sobre Sistemas Operacionais
Notas sobre Sistemas Operacionais
 
Sistemas operacionais de redes II
Sistemas operacionais de redes IISistemas operacionais de redes II
Sistemas operacionais de redes II
 
Sistemas operacionais lista de exercicios
Sistemas operacionais lista de exerciciosSistemas operacionais lista de exercicios
Sistemas operacionais lista de exercicios
 
Convercao Binario e hexadecimal
Convercao Binario e hexadecimalConvercao Binario e hexadecimal
Convercao Binario e hexadecimal
 
Sistema operacional
Sistema operacionalSistema operacional
Sistema operacional
 
Otimistas ou pessimistas - Caril Borges
Otimistas ou pessimistas - Caril BorgesOtimistas ou pessimistas - Caril Borges
Otimistas ou pessimistas - Caril Borges
 
Seminário 1º Tema parte III - Estados de processos e escalonamento de processos
Seminário 1º Tema parte III - Estados de processos e escalonamento de processosSeminário 1º Tema parte III - Estados de processos e escalonamento de processos
Seminário 1º Tema parte III - Estados de processos e escalonamento de processos
 

Semelhante a Sistemas Operacionais

Questoesde fso
Questoesde fsoQuestoesde fso
Questoesde fso
paulocsm
 
Aula 03 isc -softwares-hardwares-arquiteturas
Aula 03   isc -softwares-hardwares-arquiteturasAula 03   isc -softwares-hardwares-arquiteturas
Aula 03 isc -softwares-hardwares-arquiteturas
Fábio Andrade
 
Infraestrutura de Software - Introdução
Infraestrutura de Software - IntroduçãoInfraestrutura de Software - Introdução
Infraestrutura de Software - Introdução
Rodrigo Rodrigues
 
Revsão sobre sistemas operacionais
Revsão sobre sistemas operacionaisRevsão sobre sistemas operacionais
Revsão sobre sistemas operacionais
Rodrigo Rodrigues
 
Introducao a Sistemas Operacionais
Introducao a Sistemas OperacionaisIntroducao a Sistemas Operacionais
Introducao a Sistemas Operacionais
Isaac Vieira
 

Semelhante a Sistemas Operacionais (20)

Apostila de sistemas operacionais emi mario gurgel
Apostila de sistemas operacionais emi mario gurgelApostila de sistemas operacionais emi mario gurgel
Apostila de sistemas operacionais emi mario gurgel
 
Apostila de sistemas operacionais emi mario gurgel
Apostila de sistemas operacionais emi mario gurgelApostila de sistemas operacionais emi mario gurgel
Apostila de sistemas operacionais emi mario gurgel
 
Apostila de sistemas operacionais emi mario gurgel
Apostila de sistemas operacionais emi mario gurgelApostila de sistemas operacionais emi mario gurgel
Apostila de sistemas operacionais emi mario gurgel
 
Conceitos de sistemas operacionais
Conceitos de sistemas operacionaisConceitos de sistemas operacionais
Conceitos de sistemas operacionais
 
Sistemas Operacionais parte 2
Sistemas Operacionais  parte 2Sistemas Operacionais  parte 2
Sistemas Operacionais parte 2
 
TA1 Slides Acessibilidade - Preto e Branco.pdf
TA1 Slides Acessibilidade - Preto e Branco.pdfTA1 Slides Acessibilidade - Preto e Branco.pdf
TA1 Slides Acessibilidade - Preto e Branco.pdf
 
resumo-conceitos-de-sistemas-operacionais.pdf
resumo-conceitos-de-sistemas-operacionais.pdfresumo-conceitos-de-sistemas-operacionais.pdf
resumo-conceitos-de-sistemas-operacionais.pdf
 
Sistemas Operacionais parte 1
Sistemas Operacionais parte 1Sistemas Operacionais parte 1
Sistemas Operacionais parte 1
 
Sistemas Operacionais
Sistemas OperacionaisSistemas Operacionais
Sistemas Operacionais
 
fundamentos de sistema operacional- S.O
fundamentos de sistema operacional- S.Ofundamentos de sistema operacional- S.O
fundamentos de sistema operacional- S.O
 
Questoesde fso
Questoesde fsoQuestoesde fso
Questoesde fso
 
Aula 02
Aula 02Aula 02
Aula 02
 
Apostila SO
Apostila SOApostila SO
Apostila SO
 
Aula 03 isc -softwares-hardwares-arquiteturas
Aula 03   isc -softwares-hardwares-arquiteturasAula 03   isc -softwares-hardwares-arquiteturas
Aula 03 isc -softwares-hardwares-arquiteturas
 
Infraestrutura de Software - Introdução
Infraestrutura de Software - IntroduçãoInfraestrutura de Software - Introdução
Infraestrutura de Software - Introdução
 
Revsão sobre sistemas operacionais
Revsão sobre sistemas operacionaisRevsão sobre sistemas operacionais
Revsão sobre sistemas operacionais
 
Aula 1
Aula 1Aula 1
Aula 1
 
Trabalho de sistemas operativos
Trabalho de sistemas operativosTrabalho de sistemas operativos
Trabalho de sistemas operativos
 
Sistemas Operativos
Sistemas OperativosSistemas Operativos
Sistemas Operativos
 
Introducao a Sistemas Operacionais
Introducao a Sistemas OperacionaisIntroducao a Sistemas Operacionais
Introducao a Sistemas Operacionais
 

Mais de Daniel Paz de Araújo

Mídias Locativas em Narrativas Artísticas e Culturais
Mídias Locativas em Narrativas Artísticas e CulturaisMídias Locativas em Narrativas Artísticas e Culturais
Mídias Locativas em Narrativas Artísticas e Culturais
Daniel Paz de Araújo
 

Mais de Daniel Paz de Araújo (10)

Projeto de design editorial digital
Projeto de design editorial digitalProjeto de design editorial digital
Projeto de design editorial digital
 
Transbordamentos da Arte Contemporânea
Transbordamentos da Arte ContemporâneaTransbordamentos da Arte Contemporânea
Transbordamentos da Arte Contemporânea
 
Processing e Arduino
Processing e ArduinoProcessing e Arduino
Processing e Arduino
 
User eXperience
User eXperienceUser eXperience
User eXperience
 
Engenharia Web
Engenharia WebEngenharia Web
Engenharia Web
 
Banco de Dados
Banco de DadosBanco de Dados
Banco de Dados
 
AirCity Research - Apresentação #12.ART
AirCity Research - Apresentação #12.ARTAirCity Research - Apresentação #12.ART
AirCity Research - Apresentação #12.ART
 
Hyperbuilder: uma ferramenta para autoria de material didático estruturado pa...
Hyperbuilder: uma ferramenta para autoria de material didático estruturado pa...Hyperbuilder: uma ferramenta para autoria de material didático estruturado pa...
Hyperbuilder: uma ferramenta para autoria de material didático estruturado pa...
 
Mídias Locativas em Narrativas Artísticas e Culturais
Mídias Locativas em Narrativas Artísticas e CulturaisMídias Locativas em Narrativas Artísticas e Culturais
Mídias Locativas em Narrativas Artísticas e Culturais
 
Interface Submersiva em Jogos de Treinamentos e Negócios
Interface Submersiva em Jogos de Treinamentos e NegóciosInterface Submersiva em Jogos de Treinamentos e Negócios
Interface Submersiva em Jogos de Treinamentos e Negócios
 

Sistemas Operacionais

  • 1. Sistemas de Informação Sistemas Operacionais Daniel Paz de Araújo professor@danielpaz.net
  • 3. 1.1 Conceito básico Em torno de um computador existem usuários com problemas para serem resolvidos, por programas específicos. Para um melhor aproveitamento do hardware, vários usuários compartilham simultaneamente o computador. Os programas podem apresentar necessidades conflitantes, pois disputam os recursos do equipamento. Exemplo: disco, memória, impressora.
  • 4. 1.1 Conceito básico O S.O. é uma camada de software colocada entre o hardware e os programas que executam tarefas para os usuários. É responsável pelo acesso aos periféricos; sempre que um programa necessita de algum tipo de operação de entrada e saída. Como todos os acessos aos periféricos são feitos através do sistema operacional, ele pode controlar qual programa está acessando qual recurso. É possível, então, obter uma distribuição justa e eficiente de recursos.
  • 5. 1.1 Conceito Básico Figura 1.1: Sistema Operacional
  • 6. 1.2 Objetivos do sistema operacional O sistema operacional procura tornar a utilização do computador, ao mesmo temo, mais eficiente e mais conveniente. Maior eficiência significa mais trabalho obtido no mesmo hardware, através da distribuição de seus recursos entre os programas. Exemplo: espaço na memória, tempo de processador, impressora, espaço em disco, etc. Maior conveniência significa diminuir o tempo necessário para a construção dos programas, escondendo-se do programador detalhes do hardware. Exemplo: tipos de interface, acesso a periféricos, etc.
  • 7. 1.2.1 Tipos de serviços Execução de programas: o sistema operacional recebe o nome do arquivo, aloca memória para o programa, copia o conteúdo para a memória principal e inicia sua execução. Armazenamento de arquivos: permite a criação, escrita, leitura e exclusão de arquivos, além de operações como renomear, obter o tamanho, data de criação e outras informações a seu respeito. Acesso a periféricos: alocação, leitura, escrita e liberação, além de obtenção e alteração de informações a seu respeito.
  • 8. 1.2.1 Tipos de serviços À medida que diversos usuários compartilham o computador, passa a ser interessante saber quanto de mais recurso cada usuário necessita. Pode-se utilizar essa informação para calcular o valor a ser cobrado pelo uso do computador. Na busca de um melhor aproveitamento do hardware, diversos usuários podem compartilhar um computador. Cabe ao sistema operacional garantir que cada usuário possa trabalhar sem sofrer interferência danosa dos demais.
  • 9. 1.3 S.O. na visão do usuário A arquitetura de um sistema operacional corresponde à imagem que o usuário tem do sistema, a forma como ele percebe o sistema. Essa imagem é definida pela interface através da qual o usuário acessa os serviços do sistema operacional. Essa interface, assim como a imagem, é formada pelas chamadas de sistemas e pelos programas de sistema.
  • 10. 1.3.1 Chamadas de sistema Os programas solicitam serviços ao sistema operacional através das chamadas de sistema. Elas são semelhantes às chamadas de sub-rotinas, contudo enquanto estas são transferências para procedimentos normais do programa, as chamadas de sistema transferem a execução para o sistema operacional. Através de parâmetros, o programa informa exatamente o que necessita e o retorno da chamada de sistema, assim como retorno de uma sub-rotina, faz com que a execução do programa seja retomada a partir da instrução que segue a chamada. Exemplo: abertura de um arquivo.
  • 11. 1.3.1 Chamadas de sistema A parte do sistema operacional responsável por implementar as chamadas de sistema é normalmente chamada de núcleo ou kernel. Os principais componentes do kernel são a gerência de processador, a gerência de memória, o sistema de arquivos e a gerência de entrada e saída. Muitos sistemas operacionais são implementados em camadas, primeiro um componente de software chamado micronúcleo ou microkernel implementa os serviços mais básicos associados a sistemas operacionais. Em cima do microkernel, usando seus serviços, o kernel propriamente dito implementa os demais serviços.
  • 12. 1.3.1 Chamadas de sistema Figura 1.2: Organização do sistema em kernel e microkernel
  • 13. 1.3.2 Programas de sistema Os programas de sistema, alguma vezes chamados de utilitários, são programas normais executados fora do kernel do sistema operacional. Esses programas implementam tarefas básicas para a utilização do sistema e muitas vezes são confundidos com o próprio sistema operacional. Como implementam tarefas essenciais para a utilização do computador, são, em geral, distribuídos pelo próprio fornecedor do sistema operacional. Exemplos são os utilitários para manipulação de arquivos: programas para listar arquivo, imprimir, copiar, renomear, listar conteúdo de diretório, entre outros.
  • 14. 1.3.2 Programas de sistema O mais importante programa de sistema é o interpretador de comandos. Sua tarefa é receber comandos do usuário e executá-los. Para isso ele recebe as linhas tecladas pelo usuário, analisa seu conteúdo e executa o comando teclado. A execução do comando, na maioria das vezes, vai exigir uma ou mais chamadas de sistema. Exemplo: listagem de diretório
  • 15. 1.3.2 Programas de sistema Os mesmos conceitos sobre o interpretador de comandos é igualmente válido para a situação em que o sistema operacional oferece uma interface gráfica de usuário (GUI - graphical user interface). A única diferença está na comodidade para o usuário, que passa a usar ícones, menus e mouse no lugar de digitar comandos textuais. Programadores utilizam principalmente editores de texto e compiladores. Usuários finais utilizam aplicativos e ferramentas de apoio. O sistema operacional propriamente dito fica escondido, longe da percepção do usuário comum.
  • 16. 1.4 S.O. na visão de projeto Na visão de projeto, o mais importante é como o sistema está organizado internamente. A organização de um sistema operacional corresponde à forma como ele implementa os vários serviços. Dois tipos de eventos ativam o sistema operacional: uma chamada de sistema ou uma interrupção de periférico. É possível que a chamada de sistema envolva o acesso a um periférico. Nesse caso, o programa deverá esperar até que o periférico conclua a operação solicitada.
  • 17. 1.4 S.O. na visão de projeto Em função das chamadas de sistema, o sistema operacional envia comandos para os controladores dos periféricos. O controlador deve informar ao sistema operacional quando a operação estiver concluída. Isso é feito por intermédio de uma interrupção, quando o processador para o que está fazendo e passa a executar uma rotina específica do sistema operacional. Como a interrupção do periférico avisa o término de alguma operação de entrada e saída, possivelmente uma chamada de sistema foi concluída. Nesse caso, um programa à espera de resposta poderá ser liberado.
  • 18. 1.5 Histórico de sistemas operacionais Na década de 1940 não existia sistema operacional. O programador também é o operador do computador. Um programa tem total controle sobre a máquina, e acessa diretamente os periféricos. No máximo, existe uma biblioteca com rotinas de entrada e saída já programadas. Começou-se a utilizar operadores profissionais, assim o programador não mais opera o computador durante a execução de seu programa. Ele entrega ao operador o seu job.
  • 19. 1.5 Histórico de sistemas operacionais Entretanto, o tempo de preparação para a execução de um job continua grande. É necessário retirar as fitas magnéticas, cartões de listagem do job que terminou e preparar o próximo. Para diminuir esse tempo entre jobs, eles passam a ser agrupados em lotes. Em um mesmo lote, ou batch, são colocados jobs com necessidades semelhantes. Essa é a origem do termo sistema em batch. Um mesmo job pode exigir a execução de vários programas. Cada uma dessas etapas é chamada de step.
  • 20. 1.5 Histórico de sistemas operacionais Na década de 1950 surgiram os primeiros monitores residentes. O monitor residente é um tipo de programa que fica o tempo todo na memória. Quando um programa em execução termina, ele avisa o monitor que então, carrega automaticamente o próximo programa e inicia a execução dele. O monitor residente também é o local indicado para as rotinas de acesso aos periféricos, e são utilizadas por todos os programas. Desta forma as aplicações não precisam mais acessar diretamente os periféricos, apenas chamar a rotina apropriada dentro do monitor. Esse é o início da ideia de chamada de sistema.
  • 21. 1.5 Histórico de sistemas operacionais Na década de 1960 surgiu o conceito de multiprogramação. Em geral, periféricos são dispositivos eletromecânicos e trabalham na faixa de milissegundo. Ao mesmo tempo, o processador é um dispositivo eletrônico, que trabalha na faixa de microssegundo. Por exemplo, enquanto é feito um único acesso à leitora de cartões, poderiam ser executadas 10.000 instruções de máquina ou mais. A solução imaginada foi manter diversos programas na memória principal ao mesmo tempo. Quando um dos programas está esperando a conclusão da entrada ou saída, outro programa inicia sua execução.
  • 22. 1.5 Histórico de sistemas operacionais Duas inovações de hardware possibilitaram o desenvolvimento da multiprogramação. Interrupções: quando um comando é enviado para um periférico, imediatamente o sistema operacional inicia a execução de outro programa. É através de uma interrupção que o periférico avisa o sistema operacional quando o acesso tiver sido concluído. Pode-se fazer com que o processador fique em um laço, consultando a interface do periférico, até que a operação esteja concluída.
  • 23. 1.5 Histórico de sistemas operacionais Discos magnéticos: vários jobs são lidos de cartão perfurado ou fita magnética para o disco. Como o disco permite acesso direto a qualquer posição, é possível ler parte do primeiro job e do segundo job. À medida que, em sua função de execução, um job solicita a leitura de mais dados, eles são buscados no disco. Com a utilização de disco magnético, não havia mais a necessidade de reunir jobs semelhantes em lotes. O termo batch passou então a designar um sistema no qual não existe interação entre o usuário e a execução do programa. Mais modernamente o termo batch foi substituído por "execução em background".
  • 24. 1.5 Histórico de sistemas operacionais Na década de 1970 ocorreu a disseminação de sistemas timesharing. Em um ambiente com multiprogramação, diversos programas dividem o tempo do processador. Em um ambiente de timesharing, além da multipogramação, cada usuário possui um terminal onde ele interage com o programa em execução tendo a sensação de possuir o computador apenas para seus programas.
  • 25. 1.5 Histórico de sistemas operacionais Na década de 1980 houve uma enorme disponibilidade de microcomputadores. No início, os sistemas operacionais para microcomputadores eram bastante simples, lembrando até o velho monitor residente. À medida que o hardware dessas máquinas foi melhorado, o mesmo aconteceu com o sistema operacional.
  • 26. 1.5 Histórico de sistemas operacionais A maioria das aplicações comerciais é hoje construída em torno de bancos de dados. Ainda que a maioria dos sistemas gerenciadores de bancos de dados sejam implementados fora do sistema operacional, este deve oferecer algum suporte. Em um sistema operacional distribuído, vários computadores estão interconectados por meio de uma rede de comunicação de algum tipo. É possível, a partir de um dos computadores, acessar recursos em outros.
  • 27. 1.5 Histórico de sistemas operacionais Os sistemas operacionais de tempo real, são usados no suporte às aplicações submetidas a requisitos de natureza temporal. Nesses sistemas, os resultados devem estar corretos e não somente do ponto de vista lógico, mas também devem ser gerados no momento correto. Exemplo: lavadoras de roupa, tráfego aéreo. À medida que são desenvolvidos computadores com diversos processadores, passa a ser necessário rever aspectos básicos dos sistemas operacionals. Por exemplo, agora existe um paralelismo real a ser aproveitado. diversos programas podem ser executados realmente em paralelo, mas nem todos os processadores possuem acesso a toda a memória.
  • 28. Bibliografia OLIVEIRA, R. S. de; CARISSIMI, A. da S. e TOSCANI, S.S. Sistemas Operacionais. Porto Alegre. Bookman, 2008.
  • 30. 2.1 Mecanismo básico Em um sistema multiprogramado diversos programas são mantidos na memória ao mesmo tempo. A maioria dos programas não precisa de toda a memória do computador. Muitos programas ocupam uma pequena parcela da memória principal disponível. Sem multiprogramação, a memória não ocupada por um programa ficaria sem utilização. Com vários programas na memória, esse recurso é mais bem aproveitado.
  • 31. 2.1 Mecanismo básico Figura 2.1: Memória em um sistema com multiprogramação
  • 32. 2.2 O conceito de processo Em sistemas operacionais é conveniente diferenciar um programa de sua execução. Por exemplo, o mesmo programa pode estar sendo executado por vários usuários ao mesmo tempo. Na maioria das vezes, um processo é definido como "um programa em execução". Um programa é uma sequência de instruções e é passivo dentro do sistema, não alterando o próprio estado. O processo é um elemento ativo que altera o seu estado, à medida que executa um programa. É o processo que faz chamadas de sistema ao executar programas.
  • 33. 2.3 Ciclos de um processo Processos são criados e destruídos, porém o momento e a forma com que isso ocorre depende do sistema operacional. Algum sistemas trabalham com um número fixo de processo, sendo criados na inicialização do sistema e destruídos quando o mesmo é desligado. Outra forma é sua associação com uma sessão de trabalho, criando processos no momento do acesso do usuário ao sistema e destruindo-os quando é executada o final da sessão.
  • 34. 2.3 Ciclos de um processo A forma mais flexível de operação é permitir que os processos possam ser criados livremente, através de chamadas do sistema. Além da chamada de sistema "cria processo", serão necessárias chamadas para "autodestruição do processo"e também para a "eliminação de outro processo". A maioria dos processos de um sistema executa programas do usuário. Entretando alguns podem realizar tarefas de sistemas. São processos do sistema (daemon).
  • 35. 2.3 Ciclos de um processo Por exemplo, para evitar conflitos na utilização da impressora, muitos sistemas trabalham com uma técnica chamada spooling. Para imprimir um arquivo, o processo de usuário deve colocá-lo em um diretório especial. Um processo do sistema copia os arquivos desse diretório para a impressora. Dessa forma, um processo de usuário nunca precisa esperar a impressora ficar livre, uma vez que ele não envia os dados para a impressora, mas sim para o disco. O processo que envia os dados para a impressora não está associado a nenhum usuário.
  • 36. 2.3 Ciclos de um processo Após ter sido criado, o processo passa a ocupar o processador. Em determinados momentos, ele deixa de fazer isso para realizar uma operação de E/S. Os momentos em que um processo deseja ocupar o processador, são chamados de ciclos de processador. Quando o processo está esperando por uma operação de E/S, ele está em um ciclo de E/S. A chamada de sistema é o evento que termina o ciclo de processador em andamento e inicia um ciclo de E/S. A conclusão da chamada de sistema faz o caminho inverso.
  • 37. 2.3 Ciclos de um processo Um processo que utiliza muito processador é chamado de cpu-bound. O seu tempo de execução é definido principalmente pelo tempo dos seus ciclos de processador. Por outro lado, um processo que utiliza muita E/S é chamado de i/o-bound (input/output-bound). Nesse caso, o tempo de execução é definido principalmente pela duração das operações de E/S. Não existe uma quantificação precisa para essas definições.
  • 38. 2.4 Relacionamento entre processos Alguns sistemas suportam o conceito de grupos de processos. Se processos são criados através de chamada de sistema, pode-se considerar como pertencentes ao mesmo grupo todos os processos criados pelo mesmo processo. O conceito de grupo permite que operações possam ser aplicadas sobre todo um conjunto de processos, e não apenas sobre processos individuais. Por exemplo, os processos pertencentes a um mesmo grupo podem compartilhar os mesmos direitos perante o sistema.
  • 39. 2.4 Relacionamento entre processos Em muitos sistemas os processos são criados por outros processos, pelas chamadas de sistema. Nesse caso, é possível definir uma hierarquia de processos. O processo que faz a chamada de sistema é chamado de processo pai, enquanto o processo criado é chamado de processo filho. Um mesmo processo pai pode estar associado a vários processos filhos. Os processos filhos, por sua vez, podem criar outros processos.
  • 40. 2.4 Relacionamento entre processos Figura 2.2: Hierarquia de processos
  • 41. 2.4 Relacionamento entre processos À medida que processos são criados e destruídos, nodos são acrescentados ou removidos da árvore, respectivamente. O sistema pode definir, por exemplo, o que fazer quando um processo com filhos é destruído. Pode-se definir que, quando um processo é destruído, todos os processos que derivam dele também são destruídos. Outra solução é manter o nodo que representa o processo destruído, até que todos os seus descendentes também terminem. Uma terceira solução é vincular os processos que são filhos do processo destruído com o processo pai daquele, isto é, com o "processo avô" deles.
  • 42. 2.5 Estados de um processo Em máquinas multiprocessadoras existem diversos processadores. Nesse caso, diversos processos executam ao mesmo tempo. Porém, essa não é a situação mais comum. Vamos supor que existe um único processador no computador. Nesse caso é necessário manter uma fila com os processos aptos a ganhar o processador. Essa fila é chamada "fila de aptos" (ready queue).
  • 43. 2.5 Estados de um processo A figura 2.3 ilustra essa situação. O processo 1 ocupa o processador, enquanto os processos 2 e 3 esperam na fila de aptos. Os processos na fila do processador estão em estado de apto (ready). Um único processo ocupa o processador a cada instante. O processo que ocupa o processador está no estado executando (running). Na figura, o processo 1 está no estado executando, enquanto os processos 2 e 3 estão no estado apto.
  • 44. 2.5 Estados de um processo Figura 2.3: Fila de processos esperando pelo processador
  • 45. 2.5 Estados de um processo A figura 2.4 mostra o diagrama de estados de um processo. No estado executando, um processo pode fazer chamadas de sistema. Até a chamada de sistema ser atendida, o processo não pode continuar sua execução. Ele fica bloqueado e só volta a disputar o processador após a conclusão da chamada. Enquanto espera pelo término da chamada de sistema, o processo está no estado bloqueado (blocked).
  • 46. 2.5 Estados de um processo Figura 2.4: Diagrama de estados de um processo
  • 47. 2.5 Estados de um processo A mudança de estado de qualquer processo é iniciada por um evento. Esse evento aciona o sistema operacional, que, então, altera o estado de um ou mais processos. A transição de estado executando para bloqueado é feita através de uma chamada de sistema. Ele fica bloqueado até o atendimento e, com isso, o processador fica livre. O sistema operacional então seleciona um processo na fila de aptos para receber o processador e altera seu estado para executando. O módulo do sistema operacional que faz essa seleção é chamado escalonador (scheduler).
  • 48. 2.5 Estados de um processo Algumas chamadas de sistema são muito rápidas. Por exemplo, a leitura da hora atual. Não existe acesso a periférico, mas apenas consulta à variáveis do próprio sistema operacional. Nesse caso, o processo não precisa voltar para a fila de aptos: ele simplesmente retorna para a execução após a conclusão de chamada, o que implica um caminho do estado bloqueado para o estado executando.
  • 49. 2.5 Estados de um processo Muitos sistemas procuram evitar que um único processo monopolize a ocupação do processador. E um processo está há muito tempo no processador, ele volta para o fim da fila de aptos. Um novo processo da fila de aptos ganha o processador e assim cada processo tem a chance de executar um pouco. Esse mecanismo cria um caminho entre o estado executando e o estado apto (a figura 2.5 mostra o grafo de estados dos processos com esses novos caminhos).
  • 50. 2.5 Estados de um processo Figura 2.5: Novo diagrama de estados de um processo
  • 51. 2.6 Gerência de filas O tempo de acesso a um periférico é muito grande se comparado aos tempos de processador. Se houver mais de uma solicitação for para o mesmo periférico, não é possível enviar o comando imediatamente, pois a maioria dos controladores de periféricos não suporta dois comandos simultâneos. O segundo processo terá que esperar o periférico ficar livre. De qualquer maneira, o processador ficou livre; um terceiro processo será retirado da fila de aptos e passará a ocupar o processador.
  • 52. 2.6 Gerência de filas Quando uma solicitação é feita, é preciso verificar a fila do periférico. Se ela estiver vazia, o periférico está livre. O pedido é inserido na fila, e o comando é enviado para o controlador. Caso contrário, o periférico está ocupado e o pedido é inserido na fila, mas nada é enviado ao controlador.
  • 53. 2.6 Gerência de filas A figura 2.6 ilustra um momento específico dentro do sistema. ● O processo 1 está executando. Na fila de aptos, esperando pelo processador, estão os processos 2 e 3. ● A impressora está livre. ● Existe um acesso em andamento na unidade de disco 0, feito pelo processo 4. ● O processo 5 também solicitou um acesso à unidade 0, mas deve esperar a conclusão do pedido em andamento. ● Os processos 4 e 5 estão bloqueados, ou seja, não disputam processador. ● A unidade de disco 1 está sendo acessada em função de um pedido do processo 6.
  • 54. 2.6 Gerência de filas Figura 2.6: Filas do sistema operacional
  • 55. 2.7 Mecanismo de interrupções O mecanismo de interrupções é um recurso comum dos processadores de qualquer porte. Ele permite que um controlador de periférico chame a atenção do processador. Analogia entre as interrupções de hardware e o telefone. Uma interrupção sempre sinaliza a ocorrência de algum evento. Quando ela acontece, desvia a execução da posição atual de programa para uma rotina específica. Essa rotina, responsável por atender a interrupção, é chamada de tratador de interrupção.
  • 56. 2.7 Mecanismo de interrupções Para que a execução do programa interrompido não seja comprometida pela interrupção, é necessário que nenhum registrador seja alterado. Alguns processadores salvam automaticamente todos os registradores quando ocorre uma interrupção; outros, salvam apenas alguns, cabendo à rotina que atende à interrupção salvar os demais registradores. O local mais indicado é a pilha de execução. É usual o processador dispor de uma instrução tipo retorno de interrupção que repõe o conteúdo original dos registradores e faz o processador retomar a execução do programa interrompido.
  • 57. 2.7 Mecanismo de interrupções A função básica de um controlador de periférico é conectar o dispositivo em questão com o processador. Através do barramento, o processador é capaz de realizar operações do tipo "lê dados", "escreve dados", "reinicializa", "lê status" e "escreve comando". O controlador é responsável por traduzir essas operações em uma sequência de acionamentos eletrônicos, elétricos e mecânicos capazes de realizar a operação solicitada. Para isso, o controlador deve saber como o periférico funciona. Daí resulta que cada tipo de periférico necessita de um controlador diferente.
  • 58. 2.7 Mecanismo de interrupções A figura 2.7 mostra o diagrama de tempo resultante quando interrupções são empregadas para implementar E/S. Após enviar o comando para o controlador, o processador segue a execução do programa. Quando a operação é concluída, o controlador gera uma interrupção. O processador, então, lê os resultados do controlador.
  • 59. 2.7 Mecanismo de interrupções Figura 2.7: Linha de tempo quando interrupção é usada para implementar E/S
  • 60. 2.7 Mecanismo de interrupções A forma mais simples de identificar a origem de uma interrupção é associar a cada controlador um tipo diferente de interrupção. Dessa forma, o controlador não somente interrompe o processador, mas também informa qual o tipo de interrupção. A maioria dos processadores admite diversos tipos de interrupções. Cada tipo de interrupção é identificado por um número. Por exemplo, de 0 (zero) a 255.
  • 61. 2.7 Mecanismo de interrupções Existem momentos em que um programa não pode ser interrompido. Por exemplo, o programa pode estar alterando variáveis que também são acessadas pelo tratador de interrupções. A solução para esse problema é desligar o mecanismo de interrupções temporariamente, enquanto o programa realiza uma tarefa crítica que não pode ser interrompida. Os processadores normalmente possuem instruções para habilitar e desabilitar interrupções. Enquanto as interrupções estiverem desabilitadas, elas são ignoradas pelo processador. Elas não são perdidas, apenas ficam pendentes.
  • 62. 2.7 Mecanismo de interrupções É comum a existência de uma relação de prioridades entre os diferentes tipos de interrupções. Vamos supor que um dado processador atribui prioridade decrescente do tipo 0 até o tipo 255. Nesse caso, quando ocorre uma interrupção tipo 10, o processador automaticamente desabilita interrupções dos tipos 10 a 255 até que o atendimento da interrupção tipo 10 tenha sido concluído. Caso ocorra, durante esse intervalo de tempo, uma interrupção do tipo 5, ela é imediatamente reconhecida pelo processador. Assim, o tratador de interrupção tipo 10 é interrompido e o tratador de interrupções tipo 5 ativado.
  • 63. 2.7 Mecanismo de interrupções Figura 2.8: Ativação em cascata de tratadores de interrupção
  • 64. 2.7 Mecanismo de interrupções O endereço de um tratador de interrupção é chamado de vetor de interrupção que "aponta" para a rotina de atendimento da mesma. Em geral, existe uma tabela na memória com todos os vetores de interrupção, ou seja, com os endereços das rotinas responsáveis por tratar os respectivos tipos de interrupção. A ocorrência de uma interrupção dispara no processador uma sequência de atendimento. Toda a sequência é executada pelo hardware, comandada pela unidade de controle do processador.
  • 65. 2.7 Mecanismo de interrupções Figura 2.9: Tabela dos vetores de interrupção
  • 66. 2.7 Mecanismo de interrupções Interrupções de software (traps) são causadas pela execução de uma instrução específica para isso, tendo como parâmetro o número da interrupção que deve ser ativada. O uso mais comum para interrupções de software é a implementação das chamadas de sistema, por meio das quais os programas de usuário solicitam serviços ao sistema operacional. O endereço armazenado nas tabelas de vetores de interrupção deve mudar conforme a versão do sistema operacional, que na sua inicialização fica encarregado de colocar os endereços certos na tabela.
  • 67. 2.7 Mecanismo de interrupções As interrupções por erro, ou interrupções de exceção acontecem quando o processador detecta algum tipo de erro na execução do programa, como por exemplo, uma divisão por zero ou o acesso a uma posição de memória que na verdade não existe. O procedimento de atendimento a essa classe de interrupção é igual ao descrito anteriormente.
  • 68. 2.8 Proteção entre processos Na multiprogramação, diversos processos compartilham o computador. É necessário que o sistema operacional ofereça proteção aos processos e garanta a utilização correta do sistema. Por exemplo, um processo de usuário não pode formatar o disco. Também não se pode permitir que um processo entre em um laço infinito e, com isso, monopolize a utilização do processador.
  • 69. 2.8.1 Modos de operação do processador O sistema operacional é responsável por implementar uma proteção apropriada para o sistema e para isso, é necessário o auxílio do processador (hardware). A forma usual é definir dois modos de operação: 1. Modo usuário: algumas instruções não podem ser executadas. 2. Modo supervisor: não existem restrições, e qualquer instrução pode ser executada. Essas instruções são chamadas privilegiadas. Se um processo de usuário tentar executar uma instrução privilegiada, o hardware automaticamente gera uma interrupção e aciona o sistema operacional que poderá abortar o processo.
  • 70. 2.8.2 Proteção dos periféricos Para proteger os periféricos, as instruções de E/S são tornadas privilegiadas. A única forma de o processo de usuário realizar uma operação de E/S é através de uma chamada de sistema. Muitas arquiteturas oferecem uma instrução chamada de interrupção de software ou trap, que quando executada, apresenta um efeito semelhante ao de uma interrupção por hardware, a única diferença sendo o fato de ter sido causada pelo software e não por um evento externo vinculado ao hardware. As interrupções geradas por software também chaveiam o processador para o modo supervisor.
  • 71. 2.8.2 Proteção de periféricos Figura 2.10: Modos de operação do processador
  • 72. 2.8.3 Proteção da memória Para implementar a proteção de memória, o sistema operacional também necessita de auxílio da arquitetura. Sempre que o sistema operacional vai disparar um processo de usuário, ele carrega nos registradores de limite os valores relativos ao processo que vai executar. Ele coloca no registrador limite inferior o endereço do primeiro byte pertencente à área de trabalho do processo e no registrador limite superior é colocado o endereço do último byte válido para a sua área. A cada acesso à memória, o hardware de proteção compara o endereço gerado pelo processador com o conteúdo dos dois registradores limite e se estiver fora da área do usuário, é gerada uma interrupção.
  • 73. 2.8.3 Proteção da memória Figura 2.11: Proteção de memória com registradores de limite
  • 74. 2.8.3 Proteção da memória Algumas arquiteturas fazem o acesso aos periféricos através de posições específicas da memória. Essa técnica é chamada de E/S mapeada na memória. Nesse caso, a proteção da memória também implementa a proteção dos periféricos. Basta colocar os endereços dos periféricos fora dos limites da área do processo. O processo não será capaz de acessar o periférico sem gerar uma interrupção. Obviamente, o acesso aos registradores de limite deve ser feito através de instruções privilegiadas. Somente o sistema operacional pode alterar o seu conteúdo.
  • 75. 2.8.3 Proteção da memória Para evitar que um único processo de usuário monopolize a utilização do processador, é empregado um temporizador (timer), que é um relógio de tempo real, implementado pelo hardware, que gera interrupções de tempos em tempos. As interrupções do temporizador ativam o sistema operacional que então verifica se o processo executado já está há muito tempo com o processador. Nesse caso, o sistema pode abortar o processo por exceder o limite de tempo de execução. O controle do temporizador deve ser feito através de instruções privilegiadas.
  • 76. 2.8.3 Proteção da memória Figura 2.12: Hardware para verificação dos endereços
  • 77. 2.8.3 Proteção da memória Muitas arquiteturas não definem apenas dois modos de operação, mas vários. Em cada modo de operação, também chamado de nível de proteção, algumas operações não são permitidas. Quanto mais confiável o software, mais direitos ele recebe. Com auxílio do hardware e um sistema operacional sem falhas, é possível construir sistemas seguros, ou seja, sistemas nos quais não ocorram interferências danosas entre usuários.
  • 78. Bibliografia OLIVEIRA, R. S. de; CARISSIMI, A. da S. e TOSCANI, S.S. Sistemas Operacionais. Porto Alegre. Bookman, 2008.
  • 80. 3. Programação concorrente Um programa que é executado por apenas um processo é chamado de programa sequencial. Nesse caso, existem somente um fluxo de controle durante a execução. Um programa concorrente é executado simultaneamente por diversos processos que cooperam entre si, isso é, trocam informações, o que significa trocar dados ou realizar algum tipo de sincronização. É necessária a existência de interação entre processos para que o programa seja considerado concorrente. O termo "programação concorrente" vem do inglês concurrent programming, onde concurrent significa "acontecendo ao mesmo tempo" ou concomitantemente.
  • 81. 3.1 Motivação Um programa concorrente pode apresentar todos os tipos de erros que normalmente aparecem em programas sequenciais. Além disso, existem os erros associados com as interações entre os processos. Mesmo com todas as suas complexidades inerentes, existem muitas áreas nas quais a programação concorrente é útil. Considere um programa que deve ler registros de um arquivo, colocar em um formato apropriado e então enviar para uma impressora física.
  • 82. 3.1.1 Programa sequencial Figura 3.1: Programa sequencial acessando arquivo e impressora
  • 83. 3.1.1 Programa sequencial Figura 3.2: Linha de tempo do programa sequencial da figura 3.1
  • 84. 3.1.1 Programa sequencial Inicialmente, o processo envia um comando para a leitura do arquivo e fica bloqueado, o disco então é acionado para realizar a operação de leitura. Uma vez concluída a leitura, o processo realiza a formatação e inicia a transferência dos dados para a impressora. Observe o diagrama da figura 3.2, o disco e a impressora nunca trabalham simultaneamente, embora não exista nenhuma limitação de natureza eletrônica. O programa sequencial é que não consegue ocupar ambos.
  • 85. 3.1.2 Programa concorrente Figura 3.3: Programa concorrente acessando arquivo e impressora
  • 86. 3.1.2 Programa concorrente Figura 3.4: Linha de tempo do programa concorrente da figura 3.3
  • 87. 3.1.2 Programa concorrente O programa concorrente é mais eficiente, pois consegue manter o disco e a impressora trabalhando simultaneamente. O tempo total para realizar a impressão do arquivo é menor quando a solução concorrente é empregada. Se o processo Leitor for sempre mais rápido, o buffer ficará cheio, e então o processo Leitor terá que esperar até que o processo impressor retire algo do buffer. Por outro lado, se o processo impressor for sempre mais rápido, eventualmente o buffer ficará vazio e ele terá que esperar pelo processo leitor.
  • 88. 3.2 Paralelismo Na verdade, a maior motivação para a programação concorrente é a engenharia de software. Aplicações inerentemente paralelas são mais facilmente construídas se programação concorrente é utilizada. Estão enquadrados nesse grupo, aplicações envolvendo protocolos de comunicação, aplicações de supervisão e controle industrial, e como era de se esperar, a própria construção de um sistema operacional.
  • 89. 3.2 Paralelismo A figura 3.5 ilustra uma rede local na qual existem diversos computadores pessoais utilizados pelos usuários e existe um computador dedicado ao papel de servidor de impressão na rede. O programa "servidor de impressão" deve: receber mensagens pela rede; escrever em disco os pedaços de arquivos recebidos; enviar mensagens pela rede contendo, por exemplo, resposta às consultas sobre seu estado; ler arquivos previamente recebidos; enviar dados para a impressora. Todas essas atividades devem ser realizadas simultaneamente.
  • 90. 3.2 Paralelismo Figura 3.5: Rede local incluindo um servidor de impressão dedicado
  • 91. 3.2 Paralelismo A figura 3.6 mostra uma das possíveis soluções para a organização interna do programa concorrente "servidor de impressão". Cada círculo representa um processo. Cada flecha representa a passagem de dados de um processo para o outro. Essa passagem de dados pode ser feita, por exemplo, através de variáveis que são compartilhadas pelos processos envolvidos na comunicação.
  • 92. 3.2 Paralelismo Figura 3.6: Servidor de impressão como programa concorrente
  • 93. 3.2 Especificação do paralelismo É poissível especificar paralelimos através de comandos: ● create_process: permite a criação de um segundo fluxo de execução, paralelo àquele que executou o comando. ● exit: o fluxo de controle que o executa é imediatamente terminado. ● wait_process: permite que um fluxo de execução espere outro fluxo terminar.
  • 94. 3.2 Especificação do paralelismo Figura 3.7: Exemplo contendo os comandos create_process, exit e wait_process
  • 95. 3.2 Especificação do paralelismo É importante observar que processos paralelos podem executar em qualquer ordem. Algumas possíveis saídas: Alo do pai Alo do filho Alo do filho Filho 1 morreu Filho 2 morreu Alo do pai Alo do filho Filho 1 morreu Alo do filho Filho 2 morreu
  • 96. 3.2 Especificação do paralelismo Figura 3.8: Diagrama de tempo associada com o programa da figura 3.7
  • 97. 3.2 Especificação do paralelismo Figura 3.9: Diagrama de tempo associada com o programa da figura 3.7
  • 98. 3.2 Especificação do paralelismo Figura 3.10: Grafo de precedência para o programa da figura 3.7
  • 99. 3.2 Especificação do paralelismo Muitas vezes são usados grafos de precedência para representar o paralelismo existente em um programa. No grafo de precedência, os nodos representam trechos de código e os arcos representam relações de precedência. Um arco no nodo X para o nodo Y representa que o código associado com Y somente poderá ser executado após o término do código associado com X. Vamos supor agora que o programador deseje que, necessariamente, o processo do filho 1 termine para então o processo filho 2 iniciar.
  • 100. 3.2 Especificação do paralelismo Figura 3.11: Programa do exemplo 3.7 alterado
  • 101. 3.2 Especificação do paralelismo Uma forma mais estruturada de especificar paralelismo em programas concorrentes é conseguida com o uso dos comandos Parbegin e Parend. Enquanto o par Begin-End delimita um conjunto de comandos que serão executados sequencialmente, o par Parbegin-Parend delimita um conjunto de comandos que serão executados em paralelo. O comando que segue ao Parend somente será executado quando todos os fluxos de controle criados na execução do Parbegin-Parend tiverem terminado.
  • 102. 3.2 Especificação do paralelismo Os comandos Parbegin-Parend definem uma nova estrutura de controle para a linguagem. Nos exemplos, a sintaxe da linguagem C foi estendida com a inclusão desse novo comando. Também é possível usar uma versão menos elegante para o comando Parbegin que, entretanto, mantém sua funcionalidade. Dessa vez, Parbegin aparece como uma função de biblioteca cujos parâmetros são os nomes das funções a serem disparadas em paralelo.
  • 103. 3.2 Especificação do paralelismo Figura 3.12: Exemplo contendo os comandos Parbegin e Parend
  • 104. 3.3 Problema da seção crítica Uma forma de implementar a passagem de dados de um processo para o outro são variáveis compartilhadas pelos processos envolvidos na comunicação. A passagem acontece quando um processo escreve em uma variável que será lida por outro processo. A quantidade exata de memória compartilhada entre os processos pode variar conforme o programa. Processos podem compartilhar todo o seu espaço de endereçamento, apenas um segmento de memória, algumas estruturas de dados ou algumas variáveis. O sistema operacional arranja para que os processos acessem as mesmas posições de memória.
  • 105. 3.3 Problema de seção crítica Figura 3.13: Compartilhamento de memória
  • 106. 3.3 Problema da seção crítica Não é possível eliminar as variáveis compartilhadas de um programa concorrente quando elas são o mecanismo de comunicação entre os processos. A solução está em controlar o acesso dos processos e suas variáveis compartilhadas, de modo a garantir que um processo não acesse uma estrutura de dados enquanto essa estiver sendo utilizada por outro processo. A parte do código de um processo que acessa uma estrutura de dados compartilhada é chamada de seção crítica.
  • 107. 3.3 Problema da seção crítica Uma solução para o problema da seção crítica estará correta quando apresentar as seguintes propriedades: ● Existe exclusividade mútua entre os processos com referência na execução das respectivas seções críticas. ● Quando um processo P deseja entrar na seção crítica e nenhum outro processo está executando a sua seção crítica, o processo P não é impedido de entrar. ● Nenhum processo pode ter seu ingresso na seção crítica postergado indefinidamente, ou seja, ficar esperando para sempre. ● Não depender da velocidade relativa da execução dos processos, nem da quantidade de processadores (cores) existentes.
  • 108. 3.4 Mecanismos básicos de exclusão mútua Tipicamente, uma solução para o problema da seção crítica tem a forma de um mecanismo que controla o acesso dos processos ao código da seção crítica. Através de primitivas específicas alocadas imediatamente antes (entrada) e imediatamente depois (saída) da seção crítica, esse mecanismo age de maneira a obter-se as quatro propriedades citadas anteriormente (ou, pelo menos, a maioria delas).
  • 109. 3.4.1 Soluções em software puro Dentro da categoria dos protocolos de software puro, os mais famosos são os algoritmos de Dekker e de Peterson. Nessas soluções os processos executam um determinado algoritmo na entrada e outro na saída da seção critica. Tais algoritmos não incluem nenhuma chamada ao sistema operacional, nem o emprego de instruções privilegiadas.
  • 110. 3.4.1 Soluções em software puro Figura 3.18: Protocolo de software puro: solução de Peterson
  • 111. 3.4.1 Soluções em software puro A variável flag é um array com duas posições, cada uma indica quando o respectivo processo deseja entrar na seção crítica (valor 1 indica "quero entrar"). A variável turn contem o número do processo com a preferência no momento. O processo P0 poderá entrar na seção crítica quando P1 não deseja entrar na seção crítica ou quando a preferência no momento é para P0. Embora o algoritmo apresentado funcione apenas para dois processos, ele pode ser extendido para o caso de muitos processos.
  • 112. 3.4.1 Soluções em software puro Soluções em software puro não são muito empregados na pratica por duas razões: 1. são bastante complexas, o que dificulta a depuração dos problemas; 2. apresentam a propriedade chamada busy-waiting, quando um processo aguarda em um laço a sinalização de um evento.
  • 113. 3.4.2 Desabilitação de interrupções Através desta solução simples, toda vez que um processo vai acessar variáveis compartilhadas antes ele desabilita interrupções. Dessa forma, ele pode acessar as variáveis com a certeza de que nenhum outro processo vai ganhar o processador, dado que as interrupções (timer, disco, etc.) que deflagram o escalonador. No final da seção crítica, ele torna a habilitar as interrupções. Esse esquema é efetivamente usado nas aplicações que executam em sistemas pequenos e dedicados, como sistemas embarcados (embedded systems).
  • 114. 3.4.2 Desabilitação de interrupções Desabilitar interrupções vai contra os mecanismos de proteção e não pode ser considerado um método genérico para resolver o problema da seção crítica. Essa é uma operação proibida para processos de usuário em sistemas de propósito geral já que são instruções que só podem ser executadas em modo privilegiado. Desabilitar interrupções também diminui a eficiência do sistema à medida que periféricos não são atendidos imediatamente durante as execuções de seções críticas (interrupções ficam pendentes e são atendidas somente após a seção crítica).
  • 115. 3.4.3 Spin-lock Essa solução é baseada em uma instrução de máquina chamada "test-and-set", embora uma instrução do tipo "swap" ou "compare on store" possa ser usada também. A seção crítica será protegida por uma variável que ocupará a posição da memória. Essa variável é normalmente chamada de lock (fechadura). Quando lock contém "0", a seção crítica está livre. Quando lock contém "1", ela está ocupada. A variável é inicializada com "0". Antes de entrar na seção crítica, um processo precisa "fechar a porta", colocando "1" em lock. Entretanto ele só pode fazer isso se "a porta estiver aberta".
  • 116. 3.5 Mutex O nome mutex é derivado de "mutual exclusion" (exclusão mútua). Uma variável mutex pode assumir apenas os valores livre e ocupado. A operação lock é usada pelo processo para solicitar acesso à seção crítica (entrada); A operação unlock permite ao processo informar que não deseja mais usar a seção crítica (saída).
  • 117. 3.5.1 Implementação de mutex No caso de computadores com um único processador, a solução mais comum é desabilitar interrupções. Para computadores com vários processadores, desabilitar interrupções não basta. Nesse caso, o spin-lock é usado, pois ele impede que um outro processo, executando em outro processador, execute a operação lock ou unlock sobre o mesmo mutex.
  • 118. 3.6 Semáforos Podemos sintetizar o funcionamento das operações P e V sobre um semáforo S da seguinte forma: P (S): S.valor = S.valor - 1; Se S.valor < 0 Então bloqueia o processo, insere em S.fila V (S): S.valor = S.valor + 1; Se S.fila não está vazia Então retira processo P de S.fila, acorda P
  • 119. 3.6 Semáforos Para que semáforos funcionem corretamente, é essencial que as operações P e V sejam atômicas. Isso é, uma operação P ou V não pode ser interrompida no meio e outra operação sobre o mesmo semáforo iniciada. Semáforos tornam a proteção da seção crítica muito simples. Para cada estrutura de dados compartilhada, deve ser criado um semáforo S inicializado com o valor 1. Todo processo, antes de acessar essa estrutura, deve executar um P(S), ou seja, a operação P sobre o semáforo S associado com a estrutura de dados em questão. Ao sair da seção crítica, o processo executa V(S).
  • 120. Bibliografia OLIVEIRA, R. S. de; CARISSIMI, A. da S. e TOSCANI, S.S. Sistemas Operacionais. Porto Alegre. Bookman, 2008.
  • 121. 4. Gerenciamento de Memória
  • 122. 4.1 Introdução Historicamente, a memória principal sempre foi vista como um recurso escasso e caro. Uma das maiores preocupações dos projetistas foi desenvolver Sistemas Operacionais que não ocupassem muito espaço de memória e, ao mesmo tempo, otimizassem a utilização dos recursos computacionais. Mesmo atualmente, com a redução de custo e consequente aumento da capacidade da memória principal, seu gerenciamento é um dos fatores mais importantes no projeto de Sistemas Operacionais. Enquanto nos sistemas monoprogramáveis a gerência da memória não é muito complexa, nos sistemas multiprogramáveis essa gerência se torna crítica, devido à necessidade de se maximizar o número de usuários e aplicações utilizando eficientemente o espaço da memória principal.
  • 123. 4.1.1 Funções básicas Em geral programas são armazenados em memórias secundárias, como discos ou fitas, por ser um meio não-volátil, abundante e de baixo custo. Como o processador somente executa instruções localizadas na memória principal, o Sistema Operacional deve sempre transferir programas da memória secundária para a memória principal antes deles serem executados. Como o tempo de acesso à memória secundária é muito superior ao tempo de acesso à memória principal, o Sistema Operacional deve buscar reduzir o número de operações de E/S à memória secundária, para evitar problemas de desempenho do sistema. A gerência de memória deve tentar manter na memória principal o maior número possível de processos residentes, permitindo maximizar o compartilhamento do processador e demais recursos computacionais.
  • 124. 4.1.1 Funções básicas Mesmo na ausência de espaço livre, o sistema deve permitir que novos processos sejam aceitos e executados. Isto é possível através da transferência temporária de processos residentes na memória principal para a memória secundária, liberando espaço para novos processos. Este mecanismo é conhecido como swapping. Outra preocupação na gerência de memória é permitir a execução de programas que sejam maiores que a memória física disponível, implementando técnicas como overlay e memória virtual. Em um ambiente de multiprogramação, o sistema operacional deve proteger as áreas de memória ocupadas por cada processo, além da área onde reside o próprio sistema. Caso um programa tente realizar algum acesso indevido à memória, o sistema de alguma forma deve impedí-lo. Apesar de a gerência de memória garantir a proteção de áreas da memória, mecanismos de compartilhamento devem ser oferecidos para que diferentes processos possam trocar dados de forma protegida.
  • 125. 4.2 Alocação de memória
  • 126. 4.2.1 Alocação Contígua Simples Foi implementada nos primeiros Sistemas Operacionais, porém ainda está presente em alguns sistemas monoprogramáveis. Nesse tipo de organização, a memória principal é subdividida em duas áreas: uma para o sistema operacional e outra para o programa do usuário. Dessa forma, o programador deve desenvolver suas aplicações, preocupado, apenas, em não ultrapassar o espaço de memória disponível, ou seja, a diferença entre o tamanho total da memória principal e área ocupada pelo Sistema Operacional.
  • 127. 4.2.1 Alocação Contígua Simples Alocação Contígua Simples
  • 128. 4.2.1 Alocação Contígua Simples Esquema em que o usuário tem controle sobre toda a memória principal, inclusive a área do Sistema Operacional. Implementa controle de proteção do sistema através de registrador que delimita a área do Sistema Operacional. Fácil implementação e código reduzido, porém não utiliza os recursos computacionais de forma eficiente, pois apenas um usuário/aplicação pode dispor deste recurso.
  • 129. 4.2.2 Técnica Overlay Na alocação contígua simples, todos os programas estão limitados ao tamanho da área de memória principal disponível para o usuário. Uma solução encontrada para o problema é dividir o programa em módulos, de forma que seja possível a execução independente de cada módulo, utilizando uma mesma área de memória. Essa técnica é chamada de overlay.
  • 130. 4.2.2 Técnica Overlay Técnica Overlay
  • 131. 4.2.2 Técnica Overlay A técnica de overlay utiliza uma área de memória comum, os os módulos “não-carregados” poderão compartilhar esta área de memória (área de overlay). Sempre que um módulo “não-carregado” for referenciado pelo módulo principal, o módulo será carregado da memória secundária para a área de overlay. No caso de uma referência a um módulo já carregado, a carga não será realizada.
  • 132. 4.2.2 Técnica Overlay A definição das áreas de overlay é função do programador, através de comandos específicos das linguagem de programação utilizada. O tamanho da área de overlay é estabelecido a partir do tamanho do maior módulo. Esta técnica tem a vantagem de permitir ao programador expandir os limites da memória principal, porém deve ser utilizada com cuidado, pois pode trazer sérios problemas de desempenho, devido a possibilidade de transferência excessiva dos módulos entre a memória principal e a secundária.
  • 133. 4.2.3 Alocação Contígua Particionada Os Sistemas Operacionais evoluíram no sentido de proporcionar melhor aproveitamento dos recursos disponíveis. Nos sistemas monoprogramáveis, o processador permace grande parte do tempo ocioso e a memória principal é subutilizada. Os sistemas multiprogramáveis já são muito mais eficientes no uso do processador, necessitando assim, que diversos programas estejam na memória principal ao mesmo tempo e que novas formas de gerência da memória sejam implementadas.
  • 134. 4.2.4 Alocação Contígua Particionada Fixa Nos primeiros sistemas multiprogramáveis, a memória era dividida em pedaços de tamanho fixo, chamados partições. O tamanho das partições, estabelecido na fase de inicialização do sistema, era definido em função do tamanho dos programas que executariam no ambiente. Sempre que fossem necessárias alterações do tamanho de uma partição, o sistema deveria ser reinicializado com a nova configuração.
  • 135. 4.2.4 Alocação Contígua Particionada Fixa Alocação Contígua Particionada Fixa (Estática) - Absoluta
  • 136. 4.2.4 Alocação Contígua Particionada Fixa Inicialmente, os programas só podiam ser carregados e executados em apenas uma partição específica, mesmo se outras estivessem disponíveis. Esta limitação se devia aos compiladores e montadores, que geravam apenas código absoluto. No exemplo acima, supondo que os programas A e B estivessem sendo executados, os programas C e E não poderiam ser processados na terceira partição, mesmo esta estando livre. A esse tipo de gerência chamou-se alocação particionada estática absoluta.
  • 137. 4.2.4 Alocação Contígua Particionada Fixa Com a evolução dos compiladores, montadores, ligadores e carregadores, o código gerado deixou de ser absoluto e passou a ser realocável. No código realocável, todas as referências a endereços no programa são relativas ao início do código e não a endereços físicos de memória. Desta forma, os programas puderam ser executados a partir de qualquer partição.
  • 138. 4.2.4 Alocação Contígua Particionada Fixa Alocação Contígua Particionada Fixa (Estática) - Realocável
  • 139. 4.2.4 Alocação Contígua Particionada Fixa Supondo que na partição 1 esteja o programa C, na partição 2 o programa A e na partição 3 o programa B. Caso os programas A e B terminassem, o programa E poderia ser executado tanto na partição 2 quanto na partição 3. Para manter o controle sobre as partições alocadas, a gerência de memória mantém uma tabela com o endereço inicial de cada partição, seu tamanho, e se está em uso ou não.
  • 140. 4.2.4 Alocação Contígua Particionada Fixa Tabela de Alocação de Partições
  • 141. 4.2.4 Alocação Contígua Particionada Fixa A esse tipo de gerência chamou-se alocação particionada estática relocável. Neste esquema de memória, a proteção baseia-se em dois registradores, que indicam os limites (inferior e superior) da partição onde o programa está sendo executado.
  • 142. 4.2.4 Alocação Contígua Particionada Fixa Proteção na Alocação Particionada
  • 143. 4.2.4 Alocação Contígua Particionada Fixa Tanto nos sistemas de alocação absoluta quanto nos de alocação realocável, os programas, normalmente, não preenchem totalmente as partições onde são carregados, deixando área de memória livre. Este problema é conhecido como fragmentação interna. Exemplo de implementação: OS/MFT (Multiprogramming with Fixed Number of Tasks) da IBM
  • 144. 4.2.5 Alocação Contígua Particionada Dinâmica Na alocação particionada dinâmica ou variável, foi eliminado o conceito de partições de tamanho fixo. Nesse esquema, cada programa utilizaria o espaço necessário, tornando essa área sua partição. Como cada programa utiliza apenas o espaço que necessita, o programa de fragmentação interna não ocorre. Um outro problema começará a ocorrer, conhecido como fragmentação externa. Ele ocorre quando os programas forem terminando e deixando espaços cada vez menores na memória, não permitindo o ingresso de novos programas.
  • 145. 4.2.5 Alocação Contígua Particionada Dinâmica Alocação Contígua Particionada Dinâmica
  • 146. 4.2.5 Alocação Contígua Particionada Dinâmica Existem duas soluções para este problema. O primeiro método indica que, conforme os programas terminem, apenas os espaços livres adjacentes sejam reunidos, produzindo áreas livres de tamanho maior.
  • 147. 4.2.5 Alocação Contígua Particionada Dinâmica Primeira solução para fragmentação interna
  • 148. 4.2.5 Alocação Contígua Particionada Dinâmica A segunda solução envolve a relocação de todas as partições ocupadas, eliminando todos os espaços entre elas e criando uma única área livre contígua. Para que esta solução possa ser implementada, é necessário que o sistema tenha a capacidade de mover os diversos programas na memória principal, ou seja, realizar a relocação dinâmica.
  • 149. 4.2.5 Alocação Contígua Particionada Dinâmica Segunda solução para fragmentação interna
  • 150. 4.2.5 Alocação Contígua Particionada Dinâmica Esta técnica de gerenciamento é conhecida como alocação particionada dinâmica com relocação. Reduz em muito o problema da fragmentação, porém aumenta a complexidade do algoritmo e o consumo de recursos do sistema (processador e área de disco). Exemplo de implementação: OS/MVT (Multiprogramming with a Variable Number os Tasks) da IBM.
  • 151. 4.2.6 Estratégias de Alocação de Partição O Sistemas Operacionais implementam, basicamente, três estratégias para determinar em qual área livre um programa será carregado para execução. A melhor estratégia depende de uma série de fatores, como o tamanho dos programas a serem processados. Independente do algoritmo utilizado, o sistema possui uma lista das áreas livres, com o endereço e o tamanho de cada área.
  • 152. 4.2.6 Estratégias de Alocação de Partição Estratégias de Alocação de Partição
  • 153. 4.2.6 Estratégias de Alocação de Partição Qual partição livre alocar a um processo que pede por um tamanho X ? ● FIRST-FIT: a primeira partição livre onde caibam X bytes é escolhida; ○ A procura pode começar sempre no início da lista, ou a partir do último bloco alocado (“next-fit”). ● BEST-FIT: a partição livre de tamanho mais parecido com X bytes é escolhida (sendo igual ou maior do que X); ○ Pode se aproveitar da ordenação da lista de área ivres. ○ Pode aumentar o problema de fragmentação. ● WORST-FIT: a maior a partição livre é escolhida; ○ Diminui o problema de fragmentação, pois deixa espaços livres maiores.
  • 154. 4.2.6 Estratégias de Alocação de Partição Exemplo de Uso das Estratégias de Alocação de Partição
  • 155. Bibliografia TANEMBAUM, Andrew S. Sistemas Operacionais Modernos. 2a ed. São Paulo: Pearson, 2003.
  • 156. 5. Gerenciamento de Memória Virtual
  • 157. 5.1 Introdução Memória Virtual é uma ténica poderosa e sofisticada de gerência de memória, onde as memórias principal e secudária são combinadas, dando ao usuário a ilusão de existir uma memória muito maior que a capacidade real da memória principal. O conceito desta técnica fundamenta-se em não vincular o endereçamento feito pelo programa aos endereços físicos da memória principal. Desta forma, programas e suas estruturas de dados deixam de estar limitados ao tamanho da memória física disponível, pois podem possuir endereços associados à memória secundária. Outra vantagem é permitir um número maior de processos compartilhando a memória principal, utilizando de forma mais eficiente o processador. Também possibilita a minimização do problema da fragmentação da memória principal. A primeira implementação foi realizada no início da década de 1960, no sistema Atlas, desenvolvido na Universidade de Manchester (Kilburn, 1962). Posteriormente, a IBM introduziria este conceito comercialmente na família System/370 em 1972. Atualmente a maioria dos sistemas operacionais utilizam-se desta técnica de gerenciamento, com exceção de alguns sistemas de supercomputadores.
  • 158. 5.1 Introdução Existe um forte relacionamento entre a gerência de memória virtual e a arquitetura de hardware do sistema computacional. Por motivos de desempenho, é comum que algumas funções da gerência de memória virtual sejam implementadas diretamente no hardware. Além disso, o código do sistema operacional deve levar em consideração várias características específicas da arquitetura, especialmente o esquema de endereçamento do processador. A gerência de memória virtual, também conhecida como gerência de alocação não-contígua, aborda três técnicas que permitem sua implementação: paginação, segmentação e segmentação com paginação.
  • 159. 5.1.1 Espaço de endereçamento virtual O conceito de memória virtual se aproxima muito da idéia de um vetor, existente nas linguagens de alto nível. Quando um programa faz referência a um elemento do vetor, não há preocupação em saber a posição de memória daquele dado. O compilador encarrega-se de gerar instruções que implementam esse mecanismo, tornando-o totalmente transparente ao programador. No caso da memória virtual, a abstração ocorre em relação aos endereços dos programas e dados. Um programa no ambiente de memória virtual não faz referência a endereços físicos de memória (endereços reais), mas apenas a endereços virtuais. O momento da execução, o endereço virtual referenciado é traduzido para um endereço físico, pois o processador manipula apenas posições da memória principal. O mecanismo de tradução destes endereços é denominado como mapeamento.
  • 160. 5.1.1 Espaço de endereçamento virtual Espaços de endereçamento virtual x real
  • 161. 5.1.1 Espaço de endereçamento virtual Programas podem fazer referência a endereços virtuais que estejam fora dos limites da memória principal, não há mais a limitação do tamanho da memória física disponível. A memória secundária é utilizada como extensão da memória principal. Quando um programa é executado, apenas parte do seu código fica residente na memória principal, permanecendo o restante na memória secundária até ser referenciado. Possibilita aumentar o compartilhamento da memória principal entre muito processos. No desenvolvimento das aplicações, os programadores não necessitam preocupar-se dos endereços virtuais, uma vez que os compiladores e ligadores (linkers) se encarregam desta tarefa.
  • 162. 5.1.1 Espaço de endereçamento virtual Espaço de endereçamento virtual
  • 163. 5.1.2 Mapeamento O processador apenas executa instruções e referencia dados residentes no espaço de endereçamento real; portanto, deve existir um mecanismo que transforme os endereços virtuais em endereços reais. Esse mecanismo, conhecido por mapeamento, permite traduzir um endereço localizado no espaço virtual para um associado no espaço real. A consequencia deste mapeamento é que um programa não necessita estar necessariamente alocado em endereços contíguos na memória principal para ser executado. Nos sistemas modernos, a tarefa de tradução de endereços virtuais é realizada pelo hardware juntamente com o sistema operacional, de forma a não comprometer seu desempenho e torná-lo totalmente transparente a usuários e aplicações. O dispositivo de hardware responsável por essa tradução é conhecido como Unidade de Gerência de Memória (Memory Management Unit – MMU), sendo acionado sempre que se faz referência a um endereço virtual. Depois de traduzido, o endereço real pode ser utilizado pelo processador para o acesso à memória principal. Como cada processo tem seu próprio endereçamento virtual, o mecanismo de tradução encarrega-se de manter tabelas de mapeamento exclusivas para cada processo.
  • 164. 5.1.2 Mapeamento Tabela de Mapeamento
  • 165. 5.1.2 Mapeamento A tabela de mapeamento é uma estrutura de dados existente para cada processo. A troca de tabelas (de um processo para outro) é realizada através de um registrador, que indica a posição inicial da tabela corrente. Toda a vez que há uma mudança de contexto, o registrador é atualizado com o endereço da nova tabela. As tabelas mapeiam blocos de dados, cujo o tamanho determina o número de entradas existentes nas tabelas de mapeamento.
  • 167. 5.1.3 Alocação de Memória Virtual por Paginação Técnica de gerência de memória onde o espaço de endereçamento virtual e o espaço de endereçamento real são divididos em blocos de mesmo tamanho chamados páginas. As páginas no espaço virtual são denominadas páginas virtuais, enquanto que as páginas do espaço real são chamadas de páginas reais ou frames. Todo o mapeamento de endereço virtual em real é realizado através de tabelas de páginas. Cada processo possui sua própria tabela de páginas e cada página virtual do processo possui uma entrada na tabela, com informações de mapeamento que permitem ao sistema localizar a página real correspondente.
  • 168. 5.1.3 Alocação de Memória Virtual por Paginação Alocação de Memória Virtual por Paginação
  • 169. 5.1.3 Alocação de Memória Virtual por Paginação Quando um programa é executado, páginas virtuais são transferidas da memória secundária para a memória principal e colocadas nos frames. Nesta técnica, o endereço virtual é formado pelo número da página virtual (NPV) e por um deslocamento. O endereço físico é obtido combinando-se o endereço do frame, localizado na tabela de páginas, com o deslocamento, contido no endereço virtual. Além da informação sobre a localização da página virtual, a ETP possui outras informações, como o bit de validade (valid bit) que indica se uma página está carregada na memória principal. Se o bit for 0 (zero), indica que não a página não está carregada, mas se o valor for 1, a página está carregada na memória principal. Caso a página referenciada não esteja na memória principal, dizemos que ocorreu um page fault. Neste caso, o sistema transfere a página da memória secundária para a memória principal, realizando uma operação de E/S conhecida como page in ou paginação.
  • 170. 5.1.3 Alocação de Memória Virtual por Paginação Tradução do Endereço Virtual
  • 171. 5.1.4 Proteção e Compartilhamento de Memória Em qualquer sistema multiprogramável, onde diversas aplicações compartilham a memória principal, devem existir mecanismos para preservar as áreas de memória do sistema operacional e dos diversos processos dos usuários. Um primeiro nível de proteção é inerente ao próprio mecanismo de memória virtual por paginação, onde cada processo tem a sua própria tabela de mapeamento e a tradução dos endereços é realizada pelo sistema. Desta forma um processo não pode acessar as áreas de memória de outros processos, a menos que haja compartilhamento explícito de páginas entre os processos. A proteção de acesso é realizada individualmente em cada página da memória principal, utilizando-se as entradas das tabelas de mapeamento onde alguns bits especificam os acessos permitidos.
  • 172. 5.1.4 Proteção e Compartilhamento de Memória
  • 173. 5.1.4 Proteção e Compartilhamento de Memória ● De forma resumida há dois tipos de acessos básicos realizado em uma página: leitura e gravação. É possível a combinação destes acessos, produzindo um mecanismo simples e eficiente. Mecanismo de Proteção
  • 174. 5.1.5 Alocação de Memória Virtual por Segmentação É a técnica de gerência de memória onde o espaço de endereçamento virtual é dividido em blocos de tamanhos diferentes chamados segmentos. Na técnica de segmentação, um programa é dividido logicamente em sub-rotinas e estruturas de dados, que são alocadas em segmentos na memória principal. Há uma relação entre a lógica do programa e sua alocação na memória principal. Normalmente a definição dos segmentos é realizada pelo compilador, a partir do código fonte do programa, e cada segmento pode representar um procedimento, função, vetor ou pilha. O espaço de endereçamento virtual de um processo possui um número máximo de segmentos que podem existir, onde cada segmento pode variar de tamanho dentro de um limite. O tamanho do segmento pode ser alterado durante a execução do programa.
  • 175. 5.1.5 Alocação de Memória Virtual por Segmentação Segmentação
  • 176. 5.1.6 Alocação de Memória Virtual por Segmentação com Paginação É a técnica de gerência de memória onde o espaço de endereçamento é dividido em segmentos e, por sua vez, cada segmento dividido em páginas. Esse esquema de gerência de memória tem o objetivo de oferecer as vantagens tanto da técnica de paginação quanto da técnica de segmentação. Nessa técnica, um endereço virtual é formado pelo número do segmento virtual (NSV), um número de página virtual (NPV) e um deslocamento. Através no NSV, obtém-se uma entrada na tabela de segmentos, que contém informações da tabela de páginas do segmento. O NPV identifica unicamente a página virtual que contém o endereço, funcionando como um índice na tabela de páginas. O deslocamento indica a posição do endereço virtual em relação ao início da página na qual se encontra. O endereço físico é obtido, então, combinando-se o endereço do frame, localizado na tabela de páginas, com o deslocamento, contido no endereço virtual. Na visão do programador, sua aplicação continua sendo mapeada em segmentos de tamanhos diferentes, em função das sub-rotinas e estruturas de dados definidas no programa. Por outro lado, o sistema trata cada segmento como um conjunto de páginas de mesmo tamanho, mapeadas por uma tabela de páginas associadas ao segmento. Dessa forma, um segmento não precisa estar contíguo na memória principal, eliminando o problema da fragmentação externa encontrado na segmentação pura.
  • 177. 5.1.6 Alocação de Memória Virtual por Segmentação com Paginação Segmentação com Paginação
  • 178. 5.1.7 Swapping em Memória A técnica de swapping permite aumentar o número de processos que compartilham a memória principal e, consequentemente, o grau de multiprogramação do sistema. Quando existem novos processos para serem executados e não há memória principal livre suficiente para alocação, o sistema utiliza o swapping, selecionando um ou mais processos para saírem da memória e oferecer espaço para novos processos. Depois de escolhidos, o sistema retira os processos da memória principal para a memória secundária (swap out), onde as páginas ou segmentos são gravados em um arquivo de swap (swap file). Com os processos salvos na memória secundária, os frames ou segmentos alocados são liberados para novos processos. Porteriormente, os processos que forem retirados da memória devem retornar para a memória principal (swap in) para serem novamente executados.
  • 179. 5.1.7 Swapping em Memória Há várias políticas que podem ser aplicadas na escolha dos processos que devem ser retirados da memória principal. Todas elas buscam os processos com menor chance de serem executados em um futuro próximo, sendo que a maioria dos critérios de escolha baseiam-se no estado do processo e na sua prioridade. O swapping com base em estado seleciona, inicialmente, os processos com estado em espera; porém se estes não forem suficientes ele também selecionará os em estado de pronto com menor prioridade. O arquivo de swap é compartilhado por todos os processos que estão em execução. Cada processo tem uma área reservada no arquivo que é liberada quando o processo é eliminado. Em alguns sistemas, o arquivo de swap é, na verdade, uma área em disco reservada exclusivamente para esta função.
  • 180. 5.1.8 Trashing Pode ser definido como sendo a excessiva transferência de páginas/segmentos entre a memória principal e a memória secundária. Esse problema está presente em sistemas que implementam tanto paginação como segmentação. Na memória virtual por paginação, o thrashing ocorre em dois níveis: no do próprio processo e no do sistema. No nível do processo, a excessiva paginação ocorre devido ao elevado número de page faults gerado pelo programa em execução. Esse problema faz com que o processo passe mais tempo esperando por páginas que realmente sendo executado. No nível de sistema ocorre quando existem mais processos competindo por memória principal que espaço disponível. Neste caso, o ideal é reduzir o número de páginas de cada processo na memória, poré isto leva ao thrashing do processo. Caso a redução não seja suficiente, o sistema iniciará o swapping. Se este mecanismos for ao extremo, o sistema passará mais tempo realizando swappings que atendendo aos processos.
  • 181. 5.1.8 Trashing Em sistema que implementam segmentação, o thrashing também ocorre em dois níveis. No nível do processo, a transferência excessiva de segmentos é devida à modularização extrema do programa. E no nível do sistema é semelhante ao da paginação, com a ocorrência de swapping de processos para liberar memória para os demais. Independente das soluções apresentadas, se existirem mais processos para serem executados que memória real disponível, a única solução é a expansão da memória principal. É importante ressaltar que este problema não ocorre apenas em sistema que implementam memória virtual, mas também em sistemas com outros mecanismos de gerência de memória.
  • 182. Bibliografia TANEMBAUM, Andrew S. Sistemas Operacionais Modernos. 2a ed. São Paulo: Pearson, 2003.
  • 183. 6. Gerenciamento de Dispositivos
  • 184. 6.1 Fundamentos Uma parte bastante importante dentro dos Sistemas Operacionais é a dos mecanismos de Entradas e Saídas, através do qual o sistema se comunica com o mundo externo. Este nível é composto por processos servidores de E/S (gerentes de dispositivos e drivers) que também são processos do S.O. e também competem pelos seus recursos.
  • 185. 6.1 Fundamentos Entrada é toda instrução de envio de dados ao mundo exterior e Saída é toda instrução de recepção de dados dele. Essas instruções, em geral compreendem duas etapas: 1. Saída: ○ comandos de ação do dispositivo. ○ comandos de atribuição de dados para a operação. 2. Entrada: ○ comandos de indicação de endereços dos dados. ○ comandos de verificação do estado do dispositivo.
  • 186. 6.1 Fundamentos Portanto as instruções de E/S são sempre do tipo: ○ Sai comando; ○ Sai dados; ○ Entra dados; e ○ Entra Estado do Dispositivo. Toda operação do tipo E/S pode ser subdividida no tempo em 3 etapas distintas: 1. Início da E/S 2. Transferencia de dados 3. Finalização da operação Em geral, existe um sistema de 'RETRAY' para o caso de finalizações sem sucesso.
  • 187. 6.2 Tipos de E/S E/S com Polling (Interrogação): Implementa certo paralelismo entre a UCP e os Dispositivos de E/S. ● O programa após iniciar uma operação de E/S num dispositivo, continua executando outras tarefas (por exemplo, outra operação de E/S num outro dispositivo) e periodicamente testa o estado do dispositivo disparado para verificar se ele já completou a operação. ● É programada pelo usuário, o programa fica dependente dos aspectos físicos, além de não perder o controle da UCP. Além disso, o programa depende as características do dispositivos e perde a portabilidade.
  • 188. 6.2 Tipos de E/S E/S Assíncronas Com Interrupções: O programa inicia a operação de E/S passando comando ao dispositivo e continua outras tarefas em paralelo, até que o dispositivo encerre a operação, gerando um sinal de interrupção para a UCP para que a finalização da operação seja executada.
  • 189. 6.2 Tipos de E/S E/S Por Acesso Direto A Memória (DMA): É um mecanismo de E/S assíncrona não programada onde um dispositivo controlador de acessos a memória do sistema promove as operações de E/S diretamente, independente da participação da UCP, disputando com ela as vias de dados e endereços, e sinalização só no final da operação. ● Note que num mecanismo de interrupções sem DMA a cada operação, o dispositivo gera um sinal para a UCP a fim de completar a operação. ● No sistema de DMA, a UCP comanda um acesso passando as instruções e o endereço na memória do dado a ser transferido e o Controlador de DMA faz toda a operação e somente avisa a UCP de sua execução, sem necessidade de sua intervenção.
  • 190. 6.2 Tipos de E/S No uso de DMA, usa-se também a E/S programada para transferências de comandos e endereços ao Controlador. Informações para o Controlador: ● End. Inicial do bloco de dados na memória onde se dará a operação. ● Sentido da transferência de dados (leitura ou escrita). ● Número de células de memória a serem transferidas. OBS.: A memória só tem um porto de acesso (ponto de entrada) e um mecanismo de arbitração incorporado ao hardware define que tem direito a acessar, de acordo com sua prioridade. A prioridade maior é dada aos Controladores de ADM e depois a UCP pois sua velocidade é muito maior que a dos dispositivos. Este mecanismo é chamado Roubo de Ciclo ('cicle stealing').
  • 191. 6.2 Tipos de E/S E/S por CANAIS Característico de sistemas grandes, um Canal é um processador dedicado as funções de E/S. Pode executar Programas de canal armazenados em certos endereços da memória que a UCP passa como parâmetro ao processador de canal. ● Nos IBM: Canais de E/S. ● Nos CDC cyber: PPU (Periferal Processor Unit) Canais podem ser multiplexados por um mesmo processador de canal, de modo a ter-se em andamento várias entradas ou saídas ocorrendo em paralelo, controladas pelo mesmo processador de canal.
  • 192. 6.2 Tipos de E/S BUFFERS No histórico dos S.O., vimos que a velocidade de processamento dependia no início da velocidade dos periféricos, pois não havia até então paralelismo entre eles e a UCP. Além dos avanços no Hardware e nas formas de E/S, os sistemas mais recentes implementam formas de E/S que fazem uso de BUFFERS que são meios de armazenamento intermediários utilizados para suavizar as diferenças de velocidade de produção e consumo de dados entre a UCP e os Dispositivos. A estratégia de bufferização está baseada nos comandos de Sincronização entre processos Produtor/consumidor, tratado no capítulo sobre sincronismo, através das primitivas Wait e Signal do núcleo.
  • 193. 6.3 Camadas A gerência de dispositivos é parte do S.O. responsável por ocultar das aplicações os detalhes de controle e operação dos diversos dispositivos conectados ao sistema. A própria gerência de dispositivos é normalmente implementada em diversas camadas, de forma a proporcionar uma melhor generalização das operações de controle frente a constante evolução e mudança da tecnologia de implementação do hardware dos dispositivos.
  • 194. 6.3 Camadas ● Assim, a maioria dos S.O.s implementa a gerência de dispositivos em um esquema parecido com o abaixo representado:
  • 195. 6.3 Camadas Biblioteca de E/S Normalmente, as linguagens oferecem comando para manipular os recursos de E/S, que são o primeiro nível de interação do aplicativo com a gerência de E/S. Esses comandos são independentes até mesmo do S.O. Por exemplo, o usuário cria um arquivo em qualquer linguagem através de um comando da própria linguagem que não o obriga a saber nada sobre como será a formatação física do arquivo no disco.
  • 196. 6.3 Camadas Biblioteca de E/S O compilador da linguagem, por sua vez, traduz esses comandos em comando Chamadas de Sistema, que são os comandos oferecidos pela camada mais de cima da gerência de dispositivos e que, no desenho acima, chamamos biblioteca de E/S. Cada System call da biblioteca possui parâmetros que são passados pelo compilador da linguagem, naturalmente ainda independentemente da implementação física, e resolvidos na fase de link do programa do usuário. Além de esconder características de implementação, as Chamadas de Sistema têm por objetivo oferecer um nível onde sejam implementadas rotinas que afinal são comuns a várias linguagens e a diferentes aplicativos e que, portanto, não precisam ser duplicadas nos diferentes aplicativos ou linguagens.
  • 197. 6.3 Camadas Sistemas de E/S É a camada imediatamente abaixo na estrutura da Gerência de E/S e tem os seguintes objetivos: ● Realizar operações comuns a dispositivos distintos, sem levar em consideração aspectos específicos do dispositivo ● Fazer o mapeamento entre dispositivos lógicos e seus respectivos drivers de dispositivos físicos ● Uniformizar unidades de informação (blocos, registros, bytes, etc.) ● Gerenciar a ocorrência de alguns tipos de erros ● Controlar o compartilhamento de recursos, impondo os sincronismos que se fizerem necessários ● Controlar as prerrogativas de acesso dos usuários aos dispositivos ● Controlar a bufferização das informações com o objetivo de acelerar as operações de E/S.
  • 198. 6.3 Camadas Drivers de Software Os drivers de software, device drivers ou simplesmente drivers, manipulam um só dispositivo ou, no máximo, uma família de dispositivos. Normalmente os drivers são feitos em Assembly pelo próprio fabricante do dispositivo e são fornecidos gratuitamente quando se compra o Hardware (ou são disponibilizados da internet, por exemplo). Suas funções são: ● Receber comandos genéricos e traduzí-los para comandos específicos do dispositivo ● Manipular os registradores e demais elementos de hardware específicos do controlador
  • 199. 6.3 Camadas Drivers de Software Mapear unidades de um nível superior (como por exemplo blocos) em unidades físicas do dispositivo (como por exemplo, disco, trilhas, setores, etc.) Gerar e manipular interrupções de operações feitas por hardware dedicado (fim de transferência de um bloco de dados ou erro de transferência de dados, por exemplo).
  • 200. 6.3 Camadas Drivers de Software
  • 201. 6.3 Camadas Controladoras São placas de hardware que possuem registradores, memória local e as vezes processadores dedicados a manipular um determinado dispositivo. Em geral bufferizam a informação recebida ou enviada ao dispositivo por um barramento dedicado ou algum outro canal de comunicação e transferem os dados para a memória principal geralmente através de DMA. Assim, a CPU fica livre para realizar outras operações enquanto está se realizando a transferência de dados do/para o dispositivo.
  • 202. 6.3 Camadas Controladoras Alguns padrões de controladoras utilizados atualmente são: ● IDE interface controladora de discos magnéticos e óticos mais utilizada nos computadores pessoais. Possui um padrão mais antigo (PIO) e um mais recente (ULTRA DMA) ● SCSI (Small Computer System Interface) – define padrões de Hardware e software que permitem conectar diferentes dispositivos como discos magnéticos, óticos, scanners, unidades de fita, etc. ● USB – interface de uso geral com protocolo de rede que permite conectar virtualmente todos os dispositivos de uma máquina (inclusive teclado e mouse) e que começa a se configurar como o provavel padrão de futuro.
  • 203. 6.3 Camadas Dispositivos São os equipamentos propriamente ditos, como impressoras, discos, fitas, teclados, scanners, vídeos, registradores gráficos, etc. Podem ser divididos em estruturados e não estruturados. Estruturados são os que transferem informações em blocos (estruturas) de tamanho fixo. A transferência pode ser direta, como no caso dos discos onde se acessa diretamente o endereço de um bloco ou seqüencial, como no caso das fitas, em que é preciso percorrer seqüencialmente o meio de armazenamento. Os não estruturados são os dispositivos em que os dados fluem em lotes de tamanho indefinido, ou mesmo um a um, como é o caso dos teclados, mouse ou impressoras.
  • 204. Bibliografia TANEMBAUM, Andrew S. Sistemas Operacionais Modernos. 2a ed. São Paulo: Pearson, 2003.