Buscar

Introdução a Sistemas Operacionais

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 26 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 26 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 26 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Capítulo 1 
Introdução
Exercícios práticos 
1.1
Quais são as três finalidades principais de um sistema operacional? 
Resposta: 
Fornecer um ambiente para um usuário de computador executar programas no 
hardware do computador de uma maneira conveniente e eficiente. 
Alocar os recursos separados do computador conforme a necessidade para 
solucionar o problema. O processo de alocação deverá ser tão justo e 
eficiente quanto possível. 
Como um programa de controle, ele tem duas funções principais: (1) 
supervisão da execução dos programas do usuário para impedir erros e uso 
indevido do computador, e (2) gerenciamento da operação e controle de 
dispositivos de E/S. 
1.2
Quais são as principais diferenças entre sistemas operacionais para 
computadores de grande porte (mainframes) e computadores pessoais? 
Resposta: Geralmente, os sistemas operacionais para sistemas em bacth 
possuem requisitos mais simples do que para os computadores pessoais. Os 
sistemas em batch não precisam se preocupar com a interação com um 
usuário tanto quanto um computador pessoal. Como resultado, um sistema 
operacional para um PC precisa se preocupar com o tempo de resposta para 
um usuário interativo. Os sistemas em batch não têm esses requisitos. Um 
sistema em batch puro também pode não ter que lidar com tempo 
compartilhado, enquanto um sistema operacional precisa alternar 
rapidamente entre diferentes jobs. 
1.3
Liste as quatro etapas que são necessárias para se executar um programa 
em uma máquina completamente dedicada. 
Resposta:
a.
Reservar tempo de máquina. 
b.
Carregar programa manualmente na memória. 
c.
Carregar endereço inicial e iniciar execução. 
d.
Monitorar e controlar a execução do programa a partir do console. 
1.4
Enfatizamos a necessidade de um sistema operacional fazer uso eficiente 
do hardware de computação. Quando é apropriado que o sistema operacional 
deixe de lado esse princípio e “desperdice” recursos? Por que esse tipo 
de sistema não é realmente desperdiçador? 
Resposta: Sistemas monousuário devem maximizar o uso do sistema para o 
usuário. Uma GUI poderia “desperdiçar” ciclos de CPU, mas ela otimiza a 
interação do usuário com o sistema. 
1.5
Qual é a principal dificuldade que um programador precisa contornar na 
escrita de um sistema operacional para um ambiente de tempo real? 
Resposta: A principal dificuldade é manter o sistema operacional dentro 
das restrições de tempo fixas de um sistema de tempo real. Se o sistema 
não completar uma tarefa em determinado espaço de tempo, isso pode causar 
uma interrupção do sistema inteiro em que está rodando. Portanto, ao 
escrever um sistema operacional para um sistema de tempo real, o escritor 
precisa estar certo de que seus esquemas de escalonamento não permitam 
que o tempo de resposta exceda a restrição de tempo. 
1.6
Considere as diversas definições de sistema operacional. Considere se o 
sistema operacional deverá incluir aplicações como navegadores Web e 
programas de correio. Argumente tanto contra como a favor, e dê suporte à 
sua resposta. 
Resposta: Ponto. Aplicações como navegadores Web e ferramentas de correio 
eletrônico estão tendo um papel cada vez mais importante nos modernos 
sistemas de computador de desktop. Para atender esse papel, eles devem 
ser incorporados como parte do sistema operacional. Ao fazer isso, eles 
podem oferecer melhor desempenho e melhor integração com o restante do 
sistema. Além disso, essas aplicações importantes podem ter o mesmo 
estilo do software de sistema operacional. 
Contraponto. O papel fundamental do sistema operacional é gerenciar 
recursos do sistema como CPU, memória, dispositivos de E/S etc. Além 
disso, seu papel é executar aplicações de software como navegadores Web e 
aplicações de correio eletrônico. Incorporando essas aplicações no 
sistema operacional, sobrecarregamos o sistema operacional com 
funcionalidade adicional. Esse peso resulta no sistema operacional 
realizando uma tarefa insatisfatória no gerenciamento dos recursos do 
sistema. Além disso, aumentamos o tamanho do sistema operacional, 
aumentando assim a probabilidade de falhas do sistema e violações de 
segurança. 
1.7
Como a distinção entre o modo kernel e o modo usuário funciona como uma 
forma rudimentar de sistema de proteção (segurança)? 
Resposta: A distinção entre o modo kernel e o modo usuário oferece uma 
forma rudimentar de proteção da seguinte maneira. Certas instruções só 
poderiam ser executadas quando a CPU estivesse no modo kernel. De modo 
semelhante, dispositivos de hardware só poderiam ser acessados quando o 
programa estivesse executando no modo kernel. O controle sobre quando as 
interrupções poderiam ser ativadas ou desativada também é possível apenas 
quando a CPU estiver no modo kernel. Conseqüentemente, a CPU possui uma 
capacidade muito limitada ao executar no modo usuário, forçando assim a 
proteção de recursos críticos. 
1.8
Quais das seguintes instruções deverão ser privilegiadas? 
a.
Definir o valor do timer. 
b.
Ler o clock. 
c.
Limpar a memória. 
d.
Emitir uma instrução de trap. 
e.
Desativar interrupções. 
f.
Modificar entradas na tabela de status de dispositivo. 
g.
Passar do modo usuário para kernel. 
h.
Acessar dispositivo de E/S. 
Resposta: As operações a seguir precisam ser privilegiadas: definir valor 
do timer, limpar a memória, desativar interrupções, modificar entradas na 
tabela de status de dispositivo, acessar dispositivo de E/S. O restante 
pode ser realizado no modo usuário. 
1.9
Alguns computadores antigos protegiam o sistema operacional colocando-o 
em uma partição da memória que não poderia ser modificada pelo job do 
usuário ou pelo próprio sistema operacional. Descreva duas dificuldades 
que você acredita que poderiam surgir com tal esquema. 
Resposta: Os dados exigidos pelo sistema operacional (senhas, controles 
de acesso, informações contábeis e assim por diante) teriam que ser 
armazenadas em ou passadas pela memória desprotegida e, portanto, seriam 
acessíveis a usuários não autorizados. 
1.10
Algumas CPUs oferecem mais de dois modos de operação. Quais são os dois 
usos possíveis desses modos múltiplos? 
Resposta: Embora a maioria dos sistemas só faça a distinção entre os 
modos usuário e kernel, algumas CPUs têm suporte para modos múltiplos. 
Modos múltiplos poderiam ser usados para fornecer uma política de 
segurança mais detalhada. Por exemplo, ao invés de distinguir entre 
apenas modo usuário e kernel, você poderia distinguir entre diferentes 
tipos de modo usuário. Talvez os usuários pertencentes ao mesmo grupo 
poderiam executar o código um do outro. A máquina entraria em um modo 
especificado quando um desses usuários estivesse executando o código. 
Quando a máquina estivesse nesse modo, um membro do grupo poderia 
executar o código pertencente a qualquer outro no grupo. 
Outra possibilidade seria oferecer diferentes distinções dentro do código 
do kernel. Por exemplo, um modo específico permitiria a execução de 
drivers de dispositivo USB. Isso significaria que os dispositivos USB 
poderiam ser atendidos sem ter que passar para o modo kernel, basicamente 
permitindo que os drivers de dispositivo USB executassem em um modo quase 
usuário/kernel. 
1.11
Os timers poderiam ser usados para calcular a hora atual. Dê uma pequena 
descrição de como isso poderia ser realizado. 
Resposta: Um programa poderia usar a técnica a seguir para calcular a 
hora atual usando interrupções de timer. O programa poderia preparar um 
timer por algum tempo no futuro e ir dormir. Quando ele fosse acordado 
pela interrupção, poderia atualizar seu estado local, que está usando 
para registrar o número de interrupções que recebeu até o momento. 
Depois, poderia repetir esse processo de definir continuamente 
interrupções de timer e atualizar seu estado local quando as interrupções 
forem realmente ativadas. 
1.12
A Internet é uma LANou uma WAN?
Resposta: A Internet é uma WAN, pois os diversos computadores estão 
localizados em locais geograficamente diferentes e estão conectados por 
links de rede de longa distância. 
Capítulo 2 
Estruturas do sistema operacional 
Exercícios práticos 
2.1
Qual é a finalidade das chamadas do sistema? 
Resposta: Chamadas do sistema permitem que os processos em nível de 
usuário solicitem serviços do sistema operacional. 
2.2
Quais são as cinco principais atividades de um sistema operacional em 
relação ao gerenciamento de processos? 
Resposta: 
a.
A criação e exclusão dos processos de usuário e do sistema 
b.
A suspensão e retomada dos processos 
c.
A provisão de mecanismos para sincronismo de processo 
d.
A provisão de mecanismos para a comunicação entre processos 
e.
A provisão de mecanismos para tratamento de deadlock 
2.3
Quais são as três atividades principais de um sistema operacional em 
relação ao gerenciamento de memória? 
Resposta: 
a.
Registrar quais partes da memória estão atualmente sendo usadas e por 
quem. 
b.
Decidir quais processos devem ser carregados na memória quando o espaço 
da memória se tornar disponível. 
c.
Alocar e desalocar espaço de memória conforme a necessidade. 
2.4
Quais são as três atividades principais de um sistema operacional em 
relação ao gerenciamento de armazenamento secundário? 
Resposta: 
Gerenciamento de espaço livre. 
Alocação de armazenamento. 
Escalonamento de disco. 
2.5
Qual é a finalidade do interpretador de comandos? Por que ele normalmente 
é separado do kernel? 
Resposta: Ele lê comandos do usuário ou de um arquivo de comandos e os 
executa, normalmente transformando-os em uma ou mais chamadas do sistema. 
Ele normalmente não faz parte do kernel, pois o interpretador de comandos 
está sujeito a mudanças. 
2.6
Que chamadas do sistema precisam ser executadas por um interpretador de 
comandos ou shell a fim de inicial um novo processo? 
Resposta: Nos sistemas Unix, uma chamada do sistema fork seguida por uma 
chamada do sistema exec precisam ser realizadas para iniciar um novo 
processo. A chamada fork clona o processo atualmente em execução, 
enquanto a chamada exec sobrepõe um novo processo com base em um 
executável diferente sobre o processo que chama. 
2.7
Qual é a finalidade dos programas do sistema? 
Resposta: Os programas do sistema podem ser imaginados como grupos de 
chamadas do sistema úteis. Eles oferecem funcionalidade básica aos 
usuários, de modo que os usuários não precisem escrever seus próprios 
programas para solucionar problemas comuns. 
2.8
Qual é a principal vantagem da técnica em camadas para o projeto do 
sistema? Quais são as desvantagens do uso da técnica em camadas? 
Resposta: Em todos os casos de projeto modular, projetar um sistema 
operacional de uma maneira modular tem diversas vantagens. O sistema é 
mais fácil de depurar e modificar, pois as mudanças afetam apenas seções 
limitadas do sistema, ao invés de tocar em todas as seções do sistema 
operacional. A informação é mantida apenas onde é necessária, e é 
acessível apenas dentro de uma área definida e restrita, de modo que 
quaisquer bugs que afetem esses dados devem ser limitados a um módulo ou 
camada específica. 
2.9
Liste cinco serviços fornecidos por um sistema operacional. Explique como 
cada um oferece conveniência aos usuários. Explique também em quais casos 
seria impossível para os programas em nível de usuário oferecerem esses 
serviços. 
Resposta:
a.
Execução do programa. O sistema operacional carrega o conteúdo (ou 
seções) de um arquivo na memória e inicia sua execução. Um programa em 
nível de usuário não poderia ser confiado para alocar tempo de CPU 
corretamente. 
b.
Operações de E/S. Discos, fitas, linhas seriais e outros dispositivos 
precisam ser comunicados com um nível muito baixo. O usuários só precisa 
especificar o dispositivo e a operação a realizar sobre ele, enquanto o 
sistema converte essa solicitação em comandos específicos do dispositivo 
ou do controlador. Os programas em nível de usuário não podem ser 
confiáveis para acessar somente dispositivos que deveriam ter acesso e 
acessá-los somente quando não estiverem sendo usados. 
c.
Manipulação do sistema de arquivos. Existem muitos detalhes na criação, 
exclusão, alocação e nomeação de arquivo, que os usuários não deveriam 
ter que realizar. Blocos de espaço de disco são usados por arquivos e 
precisam ser acompanhados. A exclusão de um arquivo exige a remoção da 
informação de nome do arquivo e a liberação dos blocos alocados. As 
proteções também precisam ser verificadas para garantir o acesso 
apropriado ao arquivo. Os programas do usuário não poderiam garantir 
aderência aos métodos de proteção nem serem confiados para alocar apenas 
blocos livres e desalocar blocos na exclusão do arquivo. 
d.
Comunicações. A passagem de mensagens entre os sistemas exige que as 
mensagens sejam transformadas em pacotes de informação, enviadas ao 
controlador de rede, transmitidas por um meio de comunicação e remontadas 
pelo sistema de destino. A ordenação de pacotes e a correção de dados 
precisa ocorrer. Novamente, os programas do usuário poderiam não 
coordenar o acesso ao dispositivo de rede, ou então poderiam receber 
pacotes destinados a outros processos. 
e.
Detecção de erro. A detecção de erro ocorre nos níveis de hardware e de 
software. No nível de hardware, todas as transferências de dados precisam 
ser inspecionadas para garantir que os dados não foram modificados no 
caminho. Todos os dados na mídia precisam ser verificados para garantir 
que não tenham sido alterados desde que foram escritos na mídia. No nível 
de software, a mídia precisa ser verificada em relação à coerência dos 
dados; por exemplo, para saber se o número de blocos de armazenamento 
alocados e desalocados combina com o número total no dispositivo. Lá, os 
erros constantemente são independentes do processo (por exemplo, a 
modificação dos dados em um disco), de modo que é preciso haver um 
programa global (o sistema operacional) que trata de todos os tipos de 
erros. Além disso, tendo os erros processados pelo sistema operacional, 
os processos não precisam conter código para apanhar e corrigir todos os 
erros possíveis em um sistema. 
2.10
Qual é a finalidade das chamadas do sistema? 
Resposta: As chamadas do sistema permitem que os processos em nível de 
usuário solicitem serviços do sistema operacional. 
2.11
Quais são as principais vantagens da técnica de microkernel para o 
projeto do sistema? 
Resposta: Os benefícios normalmente incluem o seguinte: (a) a inclusão de 
um novo serviço não exige a modificação do kernel, (b) isso é mais 
seguro, pois mais operações são feitas no modo usuário do que no modo 
kernel, e (c) projeto e funcionalidade de kernel mais simples normalmente 
resulta em um sistema operacional mais confiável. 
2.12
Por que alguns sistemas armazenam o sistema operacional em firmware, e 
outros em disco? 
Resposta: Para certos dispositivos, como PDAs de mão e telefones 
celulares, um disco com um sistema de arquivos pode não estar disponível 
para o dispositivo. Nessa situação, o sistema operacional precisa ser 
armazenado no firmware. 
2.13
Como um sistema poderia ser projetado para permitir uma escolha de 
sistemas operacionais para inicializar? O que o programa de bootstrap 
precisaria fazer? 
Resposta: Considere um sistema que gostaria de executar tanto Windows XT 
quanto três distribuições diferentes do Linux (por exemplo, RedHat, 
Debian e Mandrake). Cada sistema operacional estará armazenado no disco. 
Durante a inicialização do sistema, um programa especial (que chamaremos 
de gerenciador de boot) determinará em qual sistema operacional a partida 
será dada. Isso significa que, no começo da inicialização para um sistema 
operacional, o gerenciador de boot primeiro será executado durante a 
partida do sistema. É essegerenciador de boot que é responsável por 
determinar qual sistema será iniciado. Normalmente, os gerenciadores de 
boot precisam ser armazenados em certos locais do disco rígido para serem 
reconhecidos durante a partida do sistema. Os gerenciadores de boot 
normalmente oferecem ao usuário uma seleção de sistemas; os gerenciadores 
de boot normalmente também são preparados para inicializar em um sistema 
operacional padrão, se nenhuma escolha for feita pelo usuário. 
Capítulo 3 
Processos
Exercícios práticos 
3.1
O Palm OS não fornece meios de processamento simultâneo. Discuta três 
complicações principais que o processamento simultâneo acrescenta a um 
sistema operacional. 
Resposta:
a.
Um método de compartilhamento de tempo precisa ser implementado para 
permitir que cada um dos diversos processos tenha acesso ao sistema. Esse 
método envolve a preempção dos processos que não abrem mão da CPU 
voluntariamente (usando uma chamada do sistema, por exemplo) e o kernel 
ser reentrante (de modo que mais de um processo possa estar executando o 
código do kernel simultaneamente). 
b.
Os processos e os recursos do sistema precisam ter proteções e devem ser 
protegidos um do outro. Qualquer processo precisa ser limitado na 
quantidade de memória que ele pode usar e nas operações que ele pode 
realizar sobre dispositivos como discos. 
c.
Deve-se ter o cuidado no kernel para impedir deadlocks entre os 
processos, de modo que os processos não estejam esperando pelos recursos 
alocados um do outro. 
3.2
O processador Sun UltraSPARC possui múltiplos conjuntos de registradores. 
Descreva as ações de uma troca de contexto se o novo contexto já estiver 
carregado em um dos conjuntos de registradores. O que mais precisa 
acontecer se o novo contexto estiver na memória, ao invés de um conjunto 
de registradores e todos os conjuntos de registradores estiverem em uso? 
Resposta: O ponteiro de conjunto-de-registradores-atual da CPU é alterado 
para apontar para o conjunto contendo o novo contexto, o que leva muito 
pouco tempo. Se o contexto estiver na memória, um dos contextos em um 
conjunto de registradores precisa ser escolhido e movido para a memória, 
e o novo contexto precisa ser carregado da memória para o conjunto. Esse 
processo leva um pouco mais de tempo do que em sistemas com um conjunto 
de registradores, dependendo de como uma vítima de substituição é 
selecionada. 
3.3
Quando um processo cria um novo processo usando a operação fork(), qual 
dos seguintes estados é compartilhado entre o processo pai e o processo 
filho? 
a.
Pilha 
b.
Heap
c.
Segmentos de memória compartilhada 
Resposta: Somente os segmentos de memória compartilhada são 
compartilhados entre o processo pai e o processo filho recém bifurcado. 
As cópias da pilha e da heap são feitas para o processo recém criado. 
3.4
Novamente considerando o mecanismo de RPC, considere a semântica 
“exatamente uma vez”. O algoritmo para implementar essa semântica é 
executado corretamente, mesmo que a mensagem “ACK” de volta ao cliente 
seja perdida devido a um problema de rede? Descreva a seqüência de 
mensagens e se a semântica “exatamente uma vez” ainda é preservada. 
Resposta: A semântica “exatamente uma vez” garante que um procedimento 
remoto será executado exatamente uma vez e apenas uma vez. O algoritmo 
geral para garantir isso combina um esquema de confirmação (ACK) com 
estampas de tempo (ou algum outro contador incremental que permita que o 
servidor faça a distinção entre mensagens duplicadas). A estratégia geral 
é que o cliente envie o RPC ao servidor junto com uma estampa de tempo. O 
cliente também iniciará um clock de timeout. O cliente, então, esperará 
uma de duas ocorrências: (1) ele receberá um ACK do servidor, indicando 
que o procedimento remoto foi realizado, ou (2) ele esgotará um tempo 
limite. Se o cliente esgotar o tempo limite, ele assumirá que o servidor 
não conseguiu realizar o procedimento remoto, de modo que o cliente 
invoca a RPC pela segunda vez, enviando uma estampa de tempo mais 
adiante. O cliente pode não receber o ACK por um de dois motivos: (1) a 
RPC original nunca foi recebida pelo servidor, ou (2) a RPC foi recebida 
– e executada – corretamente pelo servidor, mas o ACK foi perdido. Na 
situação (1), o uso de ACKs permite que o servidor por fim receba e 
execute a RPC. Na situação (2), o servidor receberá uma RPC duplicada e 
usará a estampa de tempo para identificá-la como uma duplicata, de modo 
que não executará a RPC pela segunda vez. É importante observar que o 
servidor precisa enviar um segundo ACK de volta ao cliente, para 
informar-lhe que a RPC foi executada. 
3.5
Considere que um sistema distribuído é suscetível a falhas no servidor. 
Que mecanismos seriam exigidos para garantir a semântica “exatamente uma 
vez” para a execução de RPCs? 
Resposta: O servidor deverá registrar no armazenamento estável (como um 
log de disco) a informação com relação às operações da RPC que foram 
recebidas, se elas foram executadas com sucesso e os resultados 
associados às operações. Quando ocorre uma falha do servidor e uma 
mensagem de RPC é recebida, o servidor pode verificar se a RPC foi 
previamente executada e, portanto, garantir a semântica “exatamente uma 
vez” para a execução de RPCs. 
Capítulo 4 
Threads
Exercícios práticos 
4.1
Forneça dois exemplos de programação em que o multithreading oferece 
melhor desempenho do que uma solução de único thread. 
Resposta: (1) Um servidor Web que atende cada solicitação em um thread 
separado. (2) Uma aplicação paralelizada, como multiplicação de matriz, 
onde diferentes partes da matriz podem ser trabalhadas em paralelo. (3) 
Um programa GUI interativo, como um depurador onde um thread é usado para 
monitorar entrada do usuário, outro thread representa a aplicação em 
execução, e um terceiro thread monitora o desempenho. 
4.2
Quais são duas diferenças entre os threads em nível de usuário e os 
threads em nível de kernel? Sob quais circunstâncias um tipo é melhor que 
o outro? 
Resposta: (1) Threads em nível de usuário são desconhecidos pelo kernel, 
enquanto o kernel está ciente dos threads de kernel. (2) Em sistemas 
usando mapeamento M:1 ou M:N, os threads do usuário são escalonados pela 
biblioteca de threads e o kernel escalona os threads de kernel. (3) Os 
threads de kernel não precisam estar associados a um processo, enquanto 
cada thread de usuário pertence a um processo. Os threads de kernel 
geralmente são mais dispendiosos de se manter do que os threads do 
usuário, pois precisam ser substituídos por uma estrutura de dados do 
kernel. 
4.3
Descreva as ações tomadas por um kernel para a troca de contexto entre os 
threads em nível de kernel. 
Resposta: A troca de contexto entre os threads de kernel normalmente 
exige salvar o valor dos registradores da CPU a partir do thread sendo 
trocado para fora, e restaurar os registradores da CPU do novo thread 
sendo escalonado. 
4.4
Que recursos são usados quando um thread é criado? Como eles diferem 
daqueles usados quando um processo é criado? 
Resposta: Como um thread é menor do que um processo, a criação de threads 
normalmente usa menos recursos do que a criação de processo. A criação de 
um processo requer a alocação de um bloco de controle de processo (PCB), 
uma estrutura de dados relativamente grande. O PCB inclui um mapa de 
memória, lista de arquivos abertos e variáveis de ambiente. A alocação e 
o gerenciamento do mapa de memória normalmente é a atividade mais 
demorada. A criação de um thread de usuário ou kernel envolve a alocação 
de uma pequena estrutura de dados para manter um conjunto de 
registradores, pilha e prioridade. 
4.5
Considere que um sistema operacional relaciona threads em nível de 
usuário ao kernel usando o modelo muitos-para-muitos e o mapeamento é 
feito por meio de LWPs. Além do mais, o sistema permite que os 
desenvolvedores criemthreads em tempo real. É necessário vincular um 
thread em tempo real a um LWP? Explique. 
Resposta: Sim. A temporização é crucial para as aplicações de tempo real. 
Se um thread for marcado como tempo real, mas ao estiver ligado a um LWP, 
o thread pode ter que esperar para ser conectado a um LPW antes de 
executar. Considere se um thread em tempo real estiver sendo executado 
(conectado a um LWP) e depois prosseguir para bloquear (ou seja, precisa 
realizar E/S, ter sido interrompido por um thread de tempo real de 
prioridade mais alta, estiver esperando por um bloqueio de exclusão mútua 
etc.) Enquanto o thread de tempo real está bloqueado, o LWP ao qual foi 
conectado foi atribuído a outro thread. Quando o thread de tempo real 
tiver sido escalonado para execução novamente, primeiro ele precisa 
esperar para ser conectado a um LWP. Vinculando um LWP a um thread de 
tempo real, você está garantindo que o thread será capaz de executar com 
o mínimo de atraso uma vez escalonado. 
4.6
Um programa Pthread que realiza a função de somatório foi apresentado na 
Seção 4.3.1. Reescreva esse programa em Java. 
Resposta: Por favor, consulte o Web site de suporte para obter o código 
fonte da solução. 
Capítulo 5 
Escalonamento de CPU 
Exercícios práticos 
5.1
Um algoritmo de escalonamento de CPU determina uma ordem para a execução 
de seus processos escalonados. Dados n processos a serem escalonados em 
um processador, quantos schedules diferentes possíveis existem? Dê uma 
fórmula em termos de n.
Resposta: n! (n fatorial = n x n - 1 x n - 2 x ... x 2 x 1). 
5.2
Defina a diferença entre escalonamento preemptivo e não preemptivo. 
Resposta: O escalonamento preemptivo permite que um processo seja 
interrompido no meio de sua execução, tirando a CPU e alocando-a a outro 
processo. O escalonamento não preemptivo garante que um processo abre mão 
do controle da CPU somente quando terminar com seu burst de CPU atual. 
5.3
Suponha que os processos a seguir cheguem para execução nos momentos 
indicados. Cada processo será executado pela quantidade de tempo listada. 
Ao responder as perguntas, use o escalonamento não preemptivo e baseie 
todas as decisões na informação que você tem no momento em que a decisão 
precisa ser tomada. 
Processo Tempo de chegada Tempo de burst
P1 0,0 8 
P2 0,4 4 
P3 1,0 1 
a.
Qual é o tempo de turnaround médio para esses processos com o algoritmo 
de escalonamento FCFS? 
b.
Qual é o tempo de turnaround médio para esses processos com o algoritmo 
de escalonamento SJF? 
c.
O algoritmo SJF deveria melhorar o desempenho, mas observe que decidimos 
executar o processo P1 no tempo 0 porque não sabíamos se dois processos 
mais curtos chegariam cedo. Calcule o tempo de turnaround médio se a CPU 
ficar ociosa pela primeira 1 unidade e depois o escalonamento SJF for 
usado. Lembre-se de que os processos P1 e P2 estão aguardando durante 
esse tempo ocioso, de modo que seu tempo de espera poderá aumentar. Esse 
algoritmo poderia ser conhecido como escalonamento com conhecimento 
futuro. 
Resposta:
a.
10,53 
b.
9,53
c.
6,86
Lembre-se de que o tempo de turnaround é o tempo de término menos o tempo 
de chegada, de modo que você precisa subtrair os tempos de chegada para 
calcular os tempos de turnaround. O FCPS é 11 se você se esquecer de 
subtrair o tempo de chegada. 
5.4
Que vantagem existe em haver diferentes tamanhos de quantum de tempo em 
diferentes níveis de um sistema de enfileiramento multinível? 
Resposta: Os processos que precisam de atendimento mais freqüente, por 
exemplo, processos interativos como editores, podem estar em uma fila com 
um pequeno quantum de tempo. Os processos sem necessidade de atendimento 
freqüente podem estar em uma fila com um quantum maior, exigindo menos 
trocas de contexto para concluir o processamento, fazendo assim um uso 
mais eficiente do computador. 
5.5
Muitos algoritmos de escalonamento de CPU são parametrizados. Por 
exemplo, o algoritmo RR requer que um parâmetro indique a fatia de tempo. 
As filas de feedback multinível exigem parâmetros para definir o número 
de filas, os algoritmos de escalonamento para cada fila, os critérios 
usados para mover processos entre as filas, e assim por diante. 
Esses algoritmos, portanto, na realidade são conjuntos de algoritmos (por 
exemplo, o conjunto de algoritmos RR para todas as fatias de tempo, e 
assim por diante). Um conjunto de algoritmos pode incluir outro (por 
exemplo, o algoritmo FCFS é o algoritmo RR com um quantum de tempo 
infinito). Que relação (se houver) existe entre os seguintes pares de 
conjuntos de algoritmos? 
a.
Prioridade e SJF
b.
Filas de feedback multinível e FCFS
c.
Prioridade e FCFS 
d.
RR e SJF
Resposta:
a.
A tarefa mais curta tem a prioridade mais alta. 
b.
O nível mais baixo de MLFQ é FCFS. 
c.
FCFS oferece a prioridade mais alta para o job que existiu por mais 
tempo. 
d.
Nenhuma. 
5.6
Suponha que um algoritmo de escalonamento (no nível de escalonamento de 
CPU a curto prazo) favorece aqueles processos que usaram o menor tempo de 
processador no passado recente. Por que esse algoritmo favorece os 
programas voltados para E/S e não deixa os programas voltados para CPU 
estagnados permanentemente? 
Resposta: Ele favorecerá os programas voltados para E/S, devido ao burst 
de CPU relativamente curto que é feito por eles; porém, os programas 
voltados para CPU não se estagnarão, pois os programas voltados para E/S 
abrirão mão da CPU com mais freqüência, para realizar sua E/S. 
5.7
Faça a distinção entre escalonamento PCS e SCS. 
Resposta: O escalonamento PCS é feito local ao processo. É assim que a 
biblioteca de threads escalona os threads nos LWPs disponíveis. O 
escalonamento SCS é a situação onde o sistema operacional escalona 
threads de kernel. Em sistemas usando muitos-para-um ou muitos-para-
muitos, os dois modelos de escalonamento são fundamentalmente diferentes. 
Em sistemas usando um-para-um, PCS e SCS são iguais. 
5.8
Considere que um sistema operacional relaciona os threads em nível de 
usuário ao modelo muitos-para-muitos, onde o mapeamento é feito por meio 
do uso de LWPs. Além do mais, o sistema permite que desenvolvedores de 
programa criem threads de tempo real. É necessário vincular um thread de 
tempo real a um LWP? 
Resposta: Sim, caso contrário um thread de usuário pode ter que competir 
por um LWP disponível antes de ser realmente escalonado. Vinculando o 
thread do usuário a um LWP, não existe latência enquanto se espera por um 
LWP disponível; o usuário de tempo real pode ser escalonado 
imediatamente. 
Capítulo 6 
Sincronismo de processos 
Exercícios práticos 
6.1
Na Seção 6.4, mencionamos que desativar interrupções com freqüência 
poderia afetar o clock do sistema. Explique por que isso poderia 
acontecer e como esses efeitos poderiam ser minimizados. 
Resposta: O clock do sistema é atualizado a cada interrupção de clock. Se 
as interrupções fossem desativadas - particularmente por um longo período 
de tempo -, é possível que o clock do sistema facilmente perdesse a hora 
correta. O clock do sistema também é usado para fins de escalonamento. 
Por exemplo, o quantum de tempo para um processo é expresso como o número 
de batidas de clock. A cada interrupção de clock, o escalonador determina 
se o quantum de tempo para o processo atualmente em execução expirou. Se 
as interrupções de clock fossem desativadas, o escalonador não poderia 
atribuir quantuns de tempo com precisão. Esse efeito pode ser minimizado 
desativando-se as interrupções de clock somente por períodos muito 
curtos. 
6.2
O problema dos fumantes de cigarro. Considere um sistema com três 
processos fumante e um processo agente. Cada fumante continuamente 
prepara um cigarro e depois o fuma. Mas, para preparar e fumar um 
cigarro, o fumante precisa de três ingredientes: tabaco, papel e 
fósforos. Um dos processos fumante tem papel,outro tem tabaco, e o 
terceiro tem fósforos. O agente tem um estoque infinito de todos os três 
materiais. O agente coloca dois dos ingredientes sobre a mesa. O fumante 
que tem o ingrediente restante, então, prepara e fuma um cigarro, 
sinalizando ao agente quando terminar. O agente, então coloca outros dois 
dos ingredientes, e o ciclo se repete. Escreva um programa para 
sincronizar o agente e os fumantes usando o sincronismo Java. 
Resposta: Por favor, consulte o Web site de suporte para obter a solução 
do código fonte. 
6.3
Dê os motivos pelos quais Solaris, Windows XP e Linux implementam 
múltiplos mecanismos de bloqueio. Descreva as circunstâncias sob as quais 
eles usam spinlocks, mutexes, semáforos, mutexes adaptativos e variáveis 
de condição. Em cada caso, explique por que o mecanismo é necessário. 
Resposta: Esses sistemas operacionais oferecem diferentes mecanismos de 
bloqueio, dependendo das necessidades dos desenvolvedores de aplicação. 
Spinlocks são úteis para sistemas multiprocessadores onde um thread pode 
executar em um loop ocupado (por um pequeno período de tempo) ao invés de 
incorrer no overhead de ser colocado em uma fila de sleep. Mutexes são 
úteis para o bloqueio de recursos. O Solaris 2 utiliza mutexes 
adaptativos, significando que o mutex é implementado com um spin lock em 
máquinas multiprocessadoras. Semáforos e variáveis de condição são 
ferramentas mais apropriadas para sincronização quando um recurso tiver 
que ser mantido por um longo período de tempo, pois o spinning é 
ineficiente por uma longa duração. 
6.4
Explique as diferenças, em termos de custo, entre os três tipos de 
armazenamento: volátil, não volátil e estável. 
Resposta: O armazenamento volátil refere-se à memória principal e de 
cache, e é muito rápido. Porém, o armazenamento volátil não pode 
sobreviver a falhas do sistema ou falta de energia no sistema. O 
armazenamento não volátil sobrevive a falhas no sistema e faltas de 
energia. Discos e fitas são exemplos de armazenamento não volátil. 
Recentemente, dispositivos USB usando memória EPROM (Erasable Program 
Read-Only Memory) apareceram oferecendo armazenamento não volátil. 
Armazenamento estável refere-se ao armazenamento que tecnicamente nunca
poderá ser perdido, pois existem cópias de backup redundantes dos dados 
(normalmente, em disco). 
6.5
Explique a finalidade do mecanismo de ponto de verificação. Com que 
freqüência os pontos de verificação devem ser realizados? Descreva como a 
freqüência dos pontos de verificação afeta: 
O desempenho do sistema quando não ocorre falha 
O tempo gasto para se recuperar de uma falha do sistema 
O tempo gasto para se recuperar de uma falha do disco 
Resposta: Um registro de logaritmo de ponto de verificação indica que um 
registro de logaritmo e seus dados modificados foram gravados em 
armazenamento estável e que a transação não precisa ser refeita no caso 
de uma falha do sistema. Obviamente, com quanto mais freqüência os pontos 
de verificação forem realizados, menor a probabilidade de que 
atualizações redundantes tenham que ser realizadas durante o processo de 
recuperação. 
O desempenho do sistema quando não ocorre falha - Se não houver falhas, o 
sistema deverá incorrer no custo de realizar pontos de verificação que 
são basicamente desnecessários. Nessa situação, a execução de pontos de 
verificação com menos freqüência levará a um melhor desempenho do 
sistema. 
O tempo gasto para se recuperar de uma falha do sistema - A existência de 
um registro de ponto de verificação significa que uma operação não terá 
que ser refeita durante a recuperação do sistema. Nessa situação, com 
quanto mais freqüência os pontos de verificação forem executados, mais 
rápido é o tempo de recuperação de uma falha do sistema. 
O tempo gasto para se recuperar de uma falha do disco - A existência de 
um registro de ponto de verificação significa que uma operação não terá 
que ser refeita durante a recuperação do sistema. Nessa situação, com 
quanto mais freqüência os pontos de verificação forem executados, mais 
rápido é o tempo de recuperação de uma falha do disco. 
6.6
Explique o conceito da atomicidade da transação. 
Resposta: Uma transação é uma série de operações de leitura e escrita 
sobre alguns dados, seguidas por uma operação de commit. Se a série de 
operações em uma transação não puder ser completada, a transação deverá 
ser abortada e as operações que ocorreram deverão ser canceladas. É 
importante que a série de operações em uma transação apareça como uma 
operação indivisível para garantir a integridade dos dados sendo 
atualizados. Caso contrário, os dados poderiam ser comprometidos se as 
operações de duas (ou mais) transações diferentes fossem intermisturadas. 
6.7
Mostre que alguns schedules são possíveis sob o protocolo de bloqueio em 
duas fases, mas não sob o protocolo de estampa de tempo, e vice-versa. 
Resposta: Um schedule que é permitido no protocolo de bloqueio em duas 
fases, mas não no protocolo de estampa de tempo, é: 
etapa T0 T1 Precedência 
1 lock-S(A) 
2 read(A) 
3 lock-X(B)
4 write(B)
5 unlock(B)
6 lock-S(B) 
7 read(B) T1 ! T0
8 unlock(A) 
9 unlock(B) 
Esse schedule não é permitido no protocolo de estampa de tempo porque, na 
etapa 7, a estampa de tempo W de B é 1. 
Um schedule que é permitido no protocolo de estampa de tempo, mas não no 
protocolo de bloqueio em duas fases, é: 
etapa T0 T1 T2
1 write(A) 
2 write(A)
3 write(A)
4 write(B) 
5 write(B)
Esse schedule não pode ter instruções de bloqueio adicionadas para torná-
la válida sob o protocolo de bloqueio em duas fases, pois T1 precisa 
desbloquear (A) entre as etapas 2 e 3, e deve bloquear (B) entre as 
etapas 4 e 5. 
6.8
A instrução [TD]wait()[TN] em todos os exemplos de programa Java fez 
parte de um loop [TD]while[TN]. Explique por que você sempre deverá ter 
que usar uma instrução [TD]while[TN] ao usar [TD]wait()[TN] e por que 
você nunca usaria uma instrução [TD]if[TN]. 
Resposta: Essa é uma questão importante para se enfatizar! Java só 
oferece notificação anônima - você não pode notificar um certo thread de 
que certa condição é verdadeira. Quando um thread é notificado, é sua 
responsabilidade verificar novamente a condição pela qual ele está 
esperando. Se um thread não verificar a condição novamente, ele pode ter 
recebido a notificação sem a condição ter sido atendida. 
Capítulo 7 
Deadlocks 
Exercícios práticos 
7.1
Liste três exemplos de deadlocks que não estão relacionados a um ambiente 
de sistema de computador. 
Resposta: 
Dois carros, vindos de direções opostas, cruzando uma ponte de única 
pista. 
Uma pessoa descendo por uma escada enquanto outra pessoa está subindo a 
mesma escada. 
Dois trens trafegando um em direção ao outro na mesma linha. 
Dois carpinteiros que precisam pregar pregos. Há um único martelo e um 
único balde de pregos. O deadlock ocorre se um carpinteiro tiver o 
martelo e o outro carpinteiro tiver os pregos. 
7.2
Suponha que um sistema esteja em um estado inseguro. Mostre que é 
possível que os processos terminem sua execução sem entrar em um estado 
de deadlock. 
Resposta: Um estado inseguro pode não necessariamente levar a um 
deadlock, mas significa apenas que não podemos garantir que o deadlock 
não ocorrerá. Assim, é possível que um sistema em um estado inseguro 
ainda possa permitir que todos os processos completem sem que ocorra 
deadlock. Considere a situação onde um sistema tem 12 recursos alocados 
entre os processos P0, P1 e P2. Os recursos são alocados de acordo com a 
seguinte política: 
 Máximo Atual Necessário 
P0 10 5 5 
P1 4 2 2 
P2 9 3 6 
[LIST]for (int i = 0; i < n; i++) { 
 // primeiro acha um thread que possa terminar 
 for (int j = 0; j < n; j++) { 
 if (!finish[j]) { 
 boolean temp = true; 
 for (int k = 0; k < m; k++) { 
 if (need[j][k] > work[k]) 
 temp =false; 
 } 
 if (temp) { // se este thread puder terminar 
 finish[j] = true; 
 for (int x = 0; x < m; x++) 
 work[x] += work[j][x]; 
 } 
 } 
 } 
}
Figura 7.1 
Algoritmo de segurança do algoritmo do banqueiro. 
Atualmente, existem dois recursos disponíveis. Esse sistema está em um 
estado inseguro, pois o processo P1 poderia completar, liberando assim um 
total de quatro recursos. Mas não podemos garantir que os processos P0 e 
P2 podem completar. Porém, é possível que um processo possa liberar 
recursos antes de solicitar algo mais. Por exemplo, o processo P2 poderia 
liberar um recurso, aumentando assim o número total de recursos para 
cinco. Isso permite que o processo P0 complete, o que liberaria um total 
de nove recursos, permitindo assim que o processo P2 complete também. 
7.3
Prove que o algoritmo de segurança apresentado na Seção 7.5.3 requer uma 
ordem de m x n2 operações. 
Resposta: A Figura 7.1 oferece um código Java que implementa o algoritmo 
de segurança do algoritmo do banqueiro (a implementação completa do 
algoritmo do banqueiro está disponível com o download do código fonte). 
Como podemos ver, os loops externos aninhados - ambos percorrendo n vezes 
- oferecem o desempenho n2. Dentro desses loops externos existem dois 
loops internos seqüenciais, que percorrem m vezes. O grande oh desse 
algoritmo é, portanto, O(m x n2). 
7.4
Considere um sistema de computação que executa 5.000 jobs por mês sem 
esquema de prevenção ou impedimento de deadlock. Os deadlocks ocorrem por 
volta de duas vezes por mês, e o operador precisa terminar e reexecutar 
cerca de 10 jobs por deadlock. Cada job tem valor aproximado de US$ 2 (em 
tempo de CPU), e os jobs terminados tendem a estar na metade quando são 
abortados. 
Um programador de sistemas estimou que um algoritmo de impedimento de 
impasse (como o algoritmo do banqueiro) poderia ser instalado no sistema 
com um aumento no tempo médio de execução por tarefa de aproximadamente 
10 por cento. Como a máquina atualmente possui um tempo ocioso de 30 por 
cento, todos os 5.000 jobs por mês ainda poderiam ser executados, embora 
o tempo de turnaround aumente em cerca de 20 por cento na média. 
a.
Quais são os argumentos a favor da instalação do algoritmo de impedimento 
de impasse? 
b.
Quais são os argumentos contra a instalação do algoritmo de impedimento 
de impasse? 
Resposta: Um argumento para se instalar o impedimento de deadlock no 
sistema é que poderíamos garantir que o impasse nunca ocorreria. Além 
disso, apesar do aumento no tempo de turnaround, todos os 5.000 jobs 
ainda poderiam executar. 
Um argumento contra a instalação do software de impedimento de deadlock é 
que os deadlocks ocorrem com pouca freqüência e eles custam pouco quando 
ocorrem. 
7.5
Um sistema poderia detectar que alguns de seus processos estão 
estagnando? Se a sua resposta for “sim”, explique como isso pode ser 
feito. Se a resposta for “não”, explique como o sistema pode lidar com o 
problema de estagnação. 
Resposta: A estagnação é um tópico difícil de definir, pois pode 
significar diferentes coisas para diferentes sistemas. Para os propósitos 
desta pergunta, definiremos a estagnação como a situação na qual o 
processo precisa esperar além de um período de tempo razoável - talvez 
indefinidamente - antes de receber um recurso solicitado. Uma forma de 
detectar a estagnação seria primeiro identificar um período de tempo - T
- que seja considerado excessivo. Quando um processo solicita um recurso, 
um temporizador é iniciado. Se o tempo gasto ultrapassar T, então o 
processo é considerado como estagnado. 
Uma estratégia para lidar com a estagnação seria adotar uma política onde 
os recursos são atribuídos apenas aos processos que estiveram esperando 
por mais tempo. Por exemplo, se o processo Pa estivesse esperando mais 
tempo pelo recurso X do que o processo Pb, a solicitação do processo Pb
seria adiada até que a solicitação do processo Pa fosse satisfeita. 
Outra estratégia seria menos estrita do que o que foi mencionado. Nesse 
cenário, um recurso poderia ser concedido a um processo que esperou menos 
do que outro processo, desde que o outro processo não esteja estagnando. 
Porém, se outro processo for considerado como estando estagnando, sua 
solicitação seria satisfeita primeiro. 
7.6
Considere a política de alocação de recursos a seguir. Solicitações e 
liberações de recursos são permitidas a qualquer momento. Se uma 
solicitação de recursos não puder ser satisfeita porque os recursos não 
estão disponíveis, então verificamos quaisquer processos que estão 
bloqueados, esperando pelos recursos. Se eles tiverem os recursos 
desejados, então esses recursos são retirados deles e dados aos processos 
solicitantes. O vetor de recursos pelos quais o processo está esperando é 
aumentado para incluir os recursos que foram retirados. 
Por exemplo, considere um sistema com três tipos de recurso e um vetor 
Available inicializado com (4,2,2). Se o processo P0 solicitar (2,2,1), 
ele os obtém. Se P1 solicitar (1,0,1), ele os obtém. Depois, se P0
solicitar (0,0,1), ele é bloqueado (recurso não disponível). Se P2 agora 
solicitar (2,0,0), ele recebe o recurso disponível (1,0,0) e um que foi 
alocado a P0 (pois P0 está bloqueado). O vetor Allocation de P0 chega até 
(1,2,1) e seu vetor Need vai até (1,0,1). 
a.
O deadlock pode ocorrer? Se a sua resposta for “sim”, dê um exemplo. Se 
você responder “não”, especifique qual condição necessária não pode 
ocorrer. 
b.
Pode ocorrer bloqueio indefinido? Explique sua resposta. 
Resposta:
a.
O deadlock não pode ocorrer porque a preempção existe. 
b.
Sim. Um processo pode nunca adquirir todos os recursos de que precisa ser 
eles forem continuamente tomados por uma série de solicitações como 
aquelas do processo C. 
7.7
Suponha que você tenha codificado o algoritmo de segurança de impedimento 
de deadlock e agora tenha que implementar o algoritmo de detecção de 
impasse. Você pode fazer isso usando simplesmente o código do algoritmo 
de segurança e redefinindo Maxi = Waitingi + Allocationi, onde Waitingi é 
um vetor especificando os recursos que o processo i está esperando, e 
Allocationi é conforme definido na Seção 7.5? Explique sua resposta. 
Resposta: Sim. O vetor Max representa a solicitação máxima que um 
processo pode fazer. Ao calcular o algoritmo de segurança, usamos a 
matriz Need que representa Max - Allocation. Outra forma de pensar nisso 
é Max = Need + Allocation. De acordo com a pergunta, a matriz Waiting
preenche um papel semelhante à matriz Need, portanto, Max = Waiting + 
Allocation.
7.8
É possível ter um deadlock envolvendo apenas um único processo? Explique 
sua resposta.
Resposta: Não. Isso segue diretamente da condição manter-e-esperar.

Continue navegando