Livro - Sistemas Operacionais
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Sistemas Operacionais
Anderson Dutra Moura
IESDE BRASIL
2020
© 2020 – IESDE BRASIL S/A.
É proibida a reprodução, mesmo parcial, por qualquer processo, sem autorização por escrito do autor e do
detentor dos direitos autorais.
Projeto de capa: IESDE BRASIL S/A.
Imagem da capa: spainter_vfx/ whiteMocca/Shutterstock
CIP-BRASIL. CATALOGAÇÃO NA PUBLICAÇÃO
SINDICATO NACIONAL DOS EDITORES DE LIVROS, RJ
M884s
Moura, Anderson Dutra
Sistemas operacionais / Anderson Dutra Moura. - 1. ed. - Curitiba
[PR] : IESDE, 2020.
164 p. : il.
Inclui bibliografia
ISBN 978-85-387-6615-5
1. Sistemas operacionais (Computadores). I. Título.
CDD: 005.43
20-64981
CDU: 004.451
Todos os direitos reservados.
IESDE BRASIL S/A.
Al. Dr. Carlos de Carvalho, 1.482. CEP: 80730-200
Batel – Curitiba – PR
0800 708 88 88 – www.iesde.com.br
Anderson Dutra
Moura
Mestre em Tecnologia da Saúde pela Pontifícia
Universidade Católica do Paraná (PUCPR). MBA em
Sistemas de Informação pela mesma instituição.
Bacharel em Ciência da Computação pela Universidade
Federal do Paraná (UFPR). Professor universitário há
mais de 15 anos em diversas instituições de ensino
superior e empresário da área de tecnologia da
informação (TI), com mais de 25 anos de experiência.
Vídeos
em QR code!
Agora é possível acessar os vídeos do livro por
meio de QR codes (códigos de barras) presentes
no início de cada seção de capítulo.
Acesse os vídeos automaticamente, direcionando
a câmera fotográfica de seu smartphone ou tablet
para o QR code.
Em alguns dispositivos é necessário ter instalado
um leitor de QR code, que pode ser adquirido
gratuitamente em lojas de aplicativos.
SUMÁRIO
1 Introdução aos sistemas operacionais 9
1.1 Evolução dos sistemas operacionais 9
1.2 Ambientes de sistemas operacionais 21
1.3 Componentes e objetivos dos sistemas operacionais 25
1.4 Arquitetura de sistemas operacionais 38
2 Interação do sistema operacional com hardware e software 45
2.1 Arquivos e diretórios 46
2.2 Interpretadores e compiladores 52
2.3 Firmware e middleware 54
2.4 Processadores 57
2.5 Memória 66
2.6 Discos e fitas 70
2.7 Dispositivos de E/S e barramentos 71
3 Processos e threads 76
3.1 Processos 76
3.2 Threads 88
3.3 Execução assíncrona concorrente 95
3.4 Programação concorrente 98
3.5 Deadlock e adiamento indefinido 100
3.6 Escalonamento de processador 103
4 Memória real e virtual 108
4.1 Memória real 108
4.2 Memória virtual 117
4.3 Questões de projeto e implementação 127
5 Segurança em sistemas operacionais 133
5.1 Criptografia 133
5.2 Autenticação 138
5.3 Controle de acesso 142
5.4 Ataques à segurança 146
5.5 Prevenção de ataques e soluções de segurança 148
5.6 Comunicação e protocolos de segurança 154
Gabarito 1611
APRESENTAÇÃO
Desde sua criação, na década de 1950, a computação evoluiu e passou a
ocupar um lugar importante no cotidiano das pessoas, seja em casa, seja no
trabalho, de um modo nunca antes visto. Na forma dos grandes computadores,
utilizados pelos centros de pesquisa e grandes corporações, computadores
pessoais, notebooks, tablets e até mesmo celulares, os dispositivos estão
presentes em nossas vidas, realizando uma quantidade de tarefas além do que
foi imaginado quando os primeiros aparelhos foram concebidos. Conectados
a redes com ou sem fio, os computadores permitiram a comunicação entre
usuários e outras máquinas separadas por longas distâncias.
Desempenhando um papel coadjuvante nessa evolução, surgiu o sistema
operacional, responsável por atender às solicitações feitas pelos usuários,
controlar e se comunicar com a infinidade de dispositivos e acessórios,
que podem ser conectados aos computadores e dispositivos; garantir a
comunicação e a segurança na troca de informações com os computadores
em rede ou que acessam a Web, entre outras tarefas.
Este livro é destinado a uma melhor compreensão do papel e das atividades
desempenhadas pelo sistema operacional. Para isso, começaremos com uma
apresentação histórica dos sistemas operacionais, seus possíveis ambientes,
seus componentes e sua arquitetura. Em seguida, apresentaremos a
forma com que o sistema operacional interage com o hardware e com o
software; a execução de tarefas pelos sistemas operacionais; a conversão de
processos em threads; o armazenamento em memória real e em memória
virtual do computador; e, finalmente, trataremos da segurança em sistemas
operacionais, as possíveis formas de ataque e defesa dos sistemas e algumas
técnicas de proteção dos dados trocados pelos computadores.
Em suma, esta obra traz as informações básicas para a compreensão do
papel dos sistemas operacionais e destina-se aos estudantes que desejam
aprofundar seus conhecimentos sobre esse coadjuvante que merece todos
os créditos por um trabalho bem realizado nos nossos computadores.
Bons estudos!
1
Introdução aos sistemas
operacionais
Se formos tomar como base o conceito de sistema operacional
da época em que ele foi criado, veríamos a definição de um
software que controla um hardware. Para aquele tempo, esse conceito
era válido. Porém, se examinarmos o hardware que temos
hoje, podemos observar que ele está interagindo com um número
cada vez maior de softwares, simultaneamente. Essa mudança na
utilização e forma de interação com o software levou à necessidade
da redefinição desse conceito; o novo papel desempenhado
pelo sistema operacional é o de realizar a separação entre as aplicações
(software e hardware), criando um controle de acesso e um
conjunto de serviços e permitindo a comunicação entre eles.
Neste capítulo, abordaremos a evolução dos sistemas operacionais,
que acompanha a evolução dos computadores e suas diversas
finalidades, tamanhos e componentes, motivando a criação
e evolução dos sistemas operacionais. Além disso, observaremos
os diferentes ambientes e tipos de sistemas nos quais os sistemas
operacionais estão inseridos, os principais componentes dos
sistemas operacionais e as características consideradas essenciais
em um sistema operacional. Por último, analisaremos a arquitetura
dos sistemas operacionais.
1.1 Evolução dos sistemas operacionais
Vídeo Segundo Deitel, Deitel e Choffnes (2005), um sistema operacional
é um software que habilita as aplicações para interagirem com
o hardware de um computador. Com a evolução dos hardwares,
suas diferentes aplicações e múltiplas possibilidades de utilização de
softwares, podemos encontrar os sistemas operacionais não somente
Introdução aos sistemas operacionais 9
Para ter uma noção do
esforço realizado pelos
pioneiros da computação,
assista ao filme O jogo
da imitação. Baseado no
livro de Alan Turing, The
Enigma, o longa-metragem
retrata a busca de
Turing para desenvolver
um computador capaz de
decodificar as mensagens
nazistas, geradas pela
máquina Enigma.
Direção: Morten Tyldum. São Paulo:
Paris Filmes, 2016.
1
Filme
A expressão bit (dígito binário -
BInary digiT) é a menor unidade
de medida de transmissão de
dados utilizada pelos computadores.
Um bit possui valor único,
podendo ser definido como zero
ou um, verdadeiro ou falso.
Filme
Para ter uma noção
da primeira e segunda
fase dos computadores,
assista ao filme Estrelas
além do tempo, que
conta a história de três
matemáticas da Nasa (Katherine
Johnson, Dorothy
Vaughn e Mary Jackson),
as quais se mostram
parte fundamental da
evolução tecnológica
durante a Guerra Fria.
Direção: Theodore Melfi. São Paulo:
WB Filmes, 2017.
em computadores de pequeno ou grande porte, mas também em nossos
celulares, geladeiras, automóveis, televisões, videogames etc.
Na maioria dos casos, a interação entre o usuário e o sistema operacional
se resume à execução de uma tarefa, como executar um aplicativo ou
copiar um arquivo. Ao receber esse comando, o sistema operacional faz
a interação entre o hardware e o software, necessária para que a tarefa
solicitada seja cumprida. Isso faz com que, para o usuário, o sistema operacional
seja um mero coadjuvante na execução das suas tarefas; porém,
ele desempenha um papel primordial nessa relação, com o hardware gerenciando
os recursos disponíveis e o software gerenciando as aplicações
em seus diferentes formatos e distribuições.
A evolução dos sistemas operacionais está intimamente ligada à
dos computadores. À medida que os computadores foram se modernizando,
por meio de novos dispositivos de hardware e novas formas
de programação, fez-se necessária a criação e adaptação dos sistemas
operacionais para realizar a comunicação entre as aplicações (software
e hardware), bem como para atender à crescente expectativa por parte
dos usuários.
A primeira fase de computadores, criados entre 1945 e 1955, se
caracterizava pelo uso de milhares de válvulas, que ocupavam enormes
áreas e ainda não faziam uso de sistemas operacionais. A interação dos
programadores com essas máquinas era feita com chaves mecânicas, nas
quais se introduziam os comandos bit-a-bit 1 , para que estes fossem convertidos
em uma linguagem que a máquina pudesse compreender.
Esse cenário somente foi melhorado com a criação dos cartões perfurados,
nos quais os comandos bit-a-bit foram transformados em sequências
no papel, acelerando o processo de programação por meio
de linguagens, como assembly, que convertiam os sinais recebidos no
cartão e permitiam a realização de operações básicas pelo computador.
Para que um programador pudesse executar um job, isto é, um programa
ou conjunto de programas, ele deveria escrevê-lo em uma folha
de papel, fazendo uso da linguagem de programação chamada de
Fortran ou em linguagem de montagem (assembly). Após essa etapa,
ele iria transferir o programa para um cartão perfurado (Figura 1). Nesse
momento, ele poderia utilizar um ou mais cartões para representar
o seu programa. Depois disso, os cartões seriam entregues para serem
processados aos operadores do computador.
10 Sistemas Operacionais
Figura 1
Cartão perfurado
ArnoldReinhold/Wikimedia Commons
O primeiro sistema operacional surgiu no início da década de 1950,
desenvolvido pelos Laboratórios de Pesquisa da General Motors, e foi
chamado de GM-NAA I/O, para ser executado nos computadores IBM
701 (Figura 2), e comercializado a partir de 1953.
O desenvolvimento do transistor e das
memórias magnéticas marcou o começo da
segunda fase de computadores, aqueles
que foram construídos entre 1955 e 1965.
A substituição das válvulas da primeira fase
pelo transistor trouxe velocidade e confiabilidade
ao processamento. Já a criação das
memórias magnéticas garantiu que os dados
fossem acessados mais rapidamente,
aumentou a capacidade de armazenamento
e permitiu que o tamanho dos computadores
fosse reduzido. Com essa evolução, os
computadores tornaram-se mais confiáveis
e passaram a ser comercializados, porém
com uso restrito para a realização de cálculos
científicos e de engenharia.
A segunda fase marcou a distinção dos
profissionais que participavam do projeto, da
construção, da operação, da programação e
da manutenção dos computadores, os quais
passaram a ser instalados em salas exclusi-
Dan/Wikimedia Commons
Figura 2
Computador IBM 701
Introdução aos sistemas operacionais 11
vas para eles, que eram acessadas somente pelo pessoal autorizado e
especializado. Em virtude do alto custo para aquisição, instalação e manutenção
desses computadores, eles eram utilizados exclusivamente
por grandes empresas, órgãos governamentais ou universidades.
Nessa fase, quando um programa (job) encerrava o seu processamento,
um dos operadores da máquina retirava o relatório de saída,
que havia sido impresso pelo programa, deixando-o na expedição. Esse
relatório seria retirado, posteriormente, pelo programador do job. Tendo
feito isso, o operador selecionava um novo grupo de cartões, que
haviam sido deixados pelos programadores na recepção, avaliando e
providenciando os recursos necessários para a execução desse novo
programa – por exemplo, a utilização do compilador Fortran, fazendo
com que o operador realizasse a leitura do grupo de cartões correspondente
ao compilador. Boa parte das atividades realizadas nessa fase estavam
concentradas no trabalho dos operadores, que circulavam pela
sala e providenciavam os recursos necessários para a execução dos
jobs que estavam sob sua responsabilidade.
Além do alto custo dos computadores, a forma como os programas
eram executados não era muito eficiente, pois dependia da inserção
manual por parte dos operadores e, enquanto não eram alimentados
por novas massas de cartões, os processadores ficavam ociosos.
Buscando reduzir o desperdício do tempo de utilização da máquina,
sua alimentação passou a seguir um novo modelo, chamado de
sistema batch (lote).
A ociosidade dos processadores era decorrente da utilização das leitoras
de cartão, como periférico de entrada, e das impressoras, como
periférico de saída. Os processadores eram lentos, quando comparados
ao processador que ficava aguardando a entrada dos dados, via
cartão, ou o final da impressão do relatório, que marcava o término de
execução do programa.
Em 1957, a utilização da fita magnética surgiu como uma opção
para resolver esse problema. Os dados dos cartões magnéticos eram
transferidos para uma fita, que posteriormente era lida pelo computador;
o mesmo ocorria com os resultados que deveriam ser impressos,
sendo copiados para uma outra fita. Assim, criando uma separação entre
sistemas, o sistema auxiliar carregava os dados na fita magnética e
12 Sistemas Operacionais
realizava a impressão, deixando o sistema principal responsável pelo
processamento.
A utilização da fita magnética para armazenamento dos dados de
entrada e dos resultados de saída foi chamada de rolamento (spooling).
Essa técnica permitia que a massa de cartões fosse gravada em uma
fita, enquanto o sistema principal executava outro programa e gravava
seus resultados em outra fita, que seria lida pelo sistema secundário,
responsável por imprimir esses dados. Com sua utilização, as tarefas
de entrada e saída foram agrupadas, maximizando o número de tarefas
processadas por unidade de tempo (throughtput) no sistema principal.
Porém, a circulação das fitas pela sala ainda consumia tempo e,
caso um programa muito longo fosse executado, ocasionava um atraso
na execução dos demais programas, em virtude da natureza sequencial
do processo.
Os programadores deixaram de se preocupar em desenvolver rotinas
de leitura/gravação específicas, para cada dispositivo periférico,
quando os sistemas operacionais incorporaram um conjunto de rotinas
para operação de entrada/saída (Input/Output Control System –
IOCS). Com isso, possibilitava-se a interdependência de dispositivos, o
que trouxe avanços, como o conceito de canal, que permitia a transferência
de dados entre dispositivos de E/S e a memória principal, sem a
participação da CPU (UCP – Unidade Central de Processamento).
A segmentação no uso dos computadores – divididos em computadores
científicos de larga escala, usados em processamento científico
e em computadores comerciais e utilizados por bancos, companhias
de seguro e departamento de recursos humanos, que realizavam operações
de pesquisa de arquivos em fita magnética e a impressão de
relatórios – marcou o surgimento da terceira fase de computadores,
abrangendo aqueles criados entre 1965 e 1980.
Entretanto, o desenvolvimento e o suporte de duas linhas de produtos
diferentes, uma para uso científico e outra para uso comercial,
representavam um grande desafio para os fabricantes na época, pois
os clientes, inicialmente, necessitavam de máquinas mais simples e,
gradualmente, foram exigindo mais agilidade no processamento e aumento
na capacidade de armazenamento. Mesmo com a atualização
de seu equipamento, o usuário poderia encontrar dificuldade em exe-
Introdução aos sistemas operacionais 13
cutar mais rápido um programa que foi desenvolvido na sua máquina
inicial, mais simples que a atual.
Buscando solucionar o problema de performance e de armazenamento,
a International Business Machine (IBM) lançou a série 360, composta
de máquinas compatíveis entre si. A série começava com o 1401,
um computador menos potente, chegando até o IBM 7094, o computador
mais potente da série. A diferença entre os computadores estava no
preço e na performance, em virtude da quantidade de memória, da velocidade
do processador, do número de dispositivos de E/S etc. A compatibilidade
dos programas a serem executados nos computadores dessa
série era garantida por uma arquitetura comum entre eles e um mesmo
conjunto de instruções básicas. Com a série 360, a IBM conseguia unir,
em um mesmo conjunto de computadores, a utilização tanto para uso
científico como para uso comercial.
Uma outra inovação trazida pela IBM, na série 360, foi a utilização dos
Circuitos Integrados (CI) ou Small Scale Integration (SSI) na sua fabricação,
o que trouxe um resultado de preço e performance muito superior
quando comparado com os computadores da fase anterior, construídos
com transistores individuais. O sucesso da série 360, que trouxe o conceito
de uma família de computadores compatíveis, fez com que os outros
fabricantes adotassem, rapidamente, essa ideia.
Realmente, a ideia da IBM era muito boa: a criação de uma família
de computadores que atendessem ao processamento comercial e ao
científico, de modo eficiente, e que permitissem qualquer programa.
Entre esses programas, estava o sistema operacional OS/360, nativo
tanto nas máquinas pequenas, que desenvolviam atividades mais simples
e gerenciavam poucos periféricos, como nas máquinas maiores,
que realizavam cálculos matemáticos mais complexos e possuíam uma
variedade muito grande de dispositivos de E/S.
Na prática, a ideia de compatibilidade da série 360 acabou se revelando
um grande problema, pois o OS/360, sistema operacional da série, era
muito complexo, sendo três vezes maior do que os sistemas operacionais
utilizados em computadores mais antigos. O OS/360 possuía muitos códigos
escritos em linguagem de máquina, apresentando um número grande
de erros, que, à medida que eram resolvidos, revelavam novos erros.
Mesmo diante da complexidade, tamanho e erros de execução, o sistema
operacional OS/360 e os sistemas operacionais de outros fabrican-
14 Sistemas Operacionais
tes, que seguiram o seu modelo, foram bem recebidos pelos usuários,
pois introduziam novas técnicas até então não disponíveis nos sistemas
operacionais, como a multiprogramação, que permitia a execução simultânea
de vários programas por meio do compartilhamento de acesso
à memória principal, ocupando em cada um deles um espaço reservado.
A evolução trazida pelo OS/360 e os sistemas de outros fabricantes
não mudou o fato de que o processamento ainda era realizado em lote,
ou seja, eles ainda eram sistemas batch. Além disso, em virtude da automatização
de muitas tarefas, os programadores começaram a sentir falta
do tempo em que tinham acesso ao computador por horas seguidas
e podiam consertar, com mais agilidade, os seus jobs. O grande desafio
era que os programadores daquela época não estavam presentes quando
seus programas eram executados – eles os deixavam em cartões
perfurados ou fitas de computador, aos cuidados do operador de sistema
responsável por carregá-los no computador para execução. Caso
ocorresse um erro durante a execução, o job era paralisado e somente
poderia ser executado novamente depois de ser corrigido, o que o fazia
entrar, mais uma vez, na fila de espera por carregamento e execução.
Com a padronização obtida pelos computadores da série 360, ao utilizar
seu modelo mais potente, o IBM 7094, evidenciou-se que, nas aplicações
científicas, as operações de E/S não eram usadas com frequência;
o contrário acontecia nas aplicações comercias, que utilizavam muito os
dispositivos de E/S, acarretando uma ociosidade por parte do processador
que, ao finalizar o job atual, ficava esperando o encerramento das
operação de E/S. Isso não era perceptível para as aplicações científicas,
mas para as comerciais representava uma perda de 80 a 90% de tempo.
A observação dessa diferença de comportamento e do desperdício
no uso do processador trouxe à tona um problema que precisava ser
solucionado.
O conceito de compartilhamento de tempo (time sharing), uma variante
da multiprogramação, surgiu em resposta à necessidade de se
conseguir melhores tempos de resposta no processamento. Com a implantação
do compartilhamento de tempo, cada usuário passou a acessar
um terminal que não possuía capacidade de processamento e que
era on-line, isto é, ligado diretamente ao computador por uma conexão
ativa. Por meio desse terminal, os programadores poderiam se comunicar
com seus programas em tempo de execução. Porém, para que essa
técnica pudesse ser disseminada, eram necessárias ações de proteção
Introdução aos sistemas operacionais 15
do hardware do computador, que passou a ser acessado pelos
programadores.
Entre os sistemas operacionais, que faziam uso de time
sharing na terceira fase dos computadores, podemos citar:
Compatible Time-
-Sharing System
(CTTS), traduzido
como sistema
compatível de tempo
compartilhado,
desenvolvido pelo
Massachusetts
Institute of
Technology (MIT).
Time sharing
system (sistema
de tempo
compartilhado),
desenvolvido
pela IBM.
O sistema Multiplexed
Information and
Computing Service
(Multics) – desenvolvido
pelo MIT, General
Electric (GE) e Bell
Laboratories para
substituir o CTTS. Seus
desenvolvedores foram
os primeiros a utilizar
o termo processo para
descrever um programa
em execução no sistema
operacional. Também
foi o primeiro sistema
operacional escrito com
uma linguagem de alto
nível (EPL) e não uma
linguagem de montagem
(assembly).
Control Program/
Conversational Monitor
System (CP/CMS)
– programa de controle/
sistema monitor
conversacional –,
que eventualmente
evoluiu para o sistema
operacional Virtual
Machine (VM) – máquina
virtual –, desenvolvido
pelo Cambridge Scientific
Center da IBM.
Vyacheslavikus/Shutterstock
Uma das conquistas dessa fase foi a diminuição do tempo de
retorno, isto é, o tempo entre a submissão de um job e o retorno de
seus resultados foi reduzido para minutos ou até segundos. Assim,
o programador não precisava esperar muito tempo para corrigir os
erros mais simples; ele dava entrada no programa e realizava a compilação,
na qual recebia uma lista dos erros de sintaxe. Isso permitia
a execução, depuração, correção e conclusão do programa com economia
de tempo.
Os sistemas operacionais TSS, Multics e CP/CMS incorporavam
o conceito de memória virtual, em que os programas conseguiam
endereçar mais localizações de memória do que as providas pela
memória principal, também chamada de memória real ou física.
Isso permitia que os programadores se preocupassem com o desenvolvimento
das aplicações e não precisassem mais atuar no gerenciamento
de memória.
16 Sistemas Operacionais
Tendo sido concebido e implementado, em 1969, na AT&T Bell
Laboratories, por Ken Thompson, Dennis Ritchie, Douglas McIlroy e
Joe Ossanna, o sistema operacional Unix foi lançado em 1971, todo
escrito em linguagem assembly. Sua versão original foi substituída,
em 1973, por uma nova versão, reescrita por Dennis Ritchie, com a linguagem
de programação C – uma linguagem de alto nível, que garantiu
a portabilidade do Unix para outras plataformas de computador.
Assim, o Unix cresceu rapidamente e se disseminou por instituições
acadêmicas e empresas, pois, em virtude de uma lei antitruste,
que proibia a AT&T de entrar no ramo de computadores, o seu
código-fonte precisou ser licenciado.
Os computadores na década de 1970 foram marcados por algumas
evoluções, como:
a. o aumento na comunicação entre sistemas de computadores
nos EUA, graças ao uso dos padrões Transmission Control
Protocol/Internet Protocol (TCP/IP), criados pelo departamento
de defesa americano, que passaram a ser utilizados em larga
escala, especialmente no meio militar e acadêmico;
b. o padrão Ethernet, desenvolvido pelo Palo Alto Research
Center (PARC) da Xerox, que popularizou a comunicação em
redes locais (Local Area Network – LAN);
c. o microprocessador comercial criado pela Intel, tendo como
destaque o modelo 8080, que serviu de base para os primeiros
microcomputadores pessoais, e fazendo uso do sistema operacional
Control Program Monitor (CP/M), também criado pela Intel.
Em virtude dessas evoluções e com o aumento da transferência de
dados em ambientes vulneráveis, a segurança se tornou um problema.
Isso aumentou a responsabilidade dos sistemas operacionais, que
passaram a atender as novas demandas, como as funcionalidades de
redes e de segurança, além da melhoria no desempenho, por causa
das demandas comerciais.
O desenvolvimento da integração de circuitos em grande escala
(LSI – Large-scale Integration) marcou o início da quarta fase de
computadores, produzidos a partir de 1981, época em que surgiram
os chips, nos quais milhares de transistores estavam encapsulados
em 1 cm² de silício. Esse fato permitiu o desenvolvimento do
conceito de computador pessoal.
Introdução aos sistemas operacionais 17
O surgimento de softwares, como planilhas de cálculo, editores de
texto, bancos de dados e pacotes gráficos, ajudou a dar impulso à revolução
da computação pessoal, criando uma demanda entre as empresas,
as quais podiam usar esses aplicativos para aumentar sua produtividade.
Nessa fase, a aquisição de computadores por empresas ou universidades
foi facilitada pelo surgimento de oferta dos minicomputadores
– como os da classe PDP-11, desenvolvidos pela Digital Equipment
Corporation (DEC) –, que não eram muito diferentes em termos de arquitetura
dos computadores pessoais.
Também, nessa fase, surgiu o conceito de rede, que permitia a troca
de informações entre os computadores pessoais ligados a ela. A evolução
desse conceito é a internet, com a qual a maioria dos computadores
pessoais estão conectados atualmente. Os computadores pessoais
mais poderosos passaram a ser chamados de workstations (estações de
trabalho) e eram usados nas mais diferentes atividades.
Figura 3
Apple Macintosh
Com o desenvolvimento e a disseminação dos computadores, os
softwares também precisaram passar por uma evolução, para que se
tornassem o mais amigável possível para o usuário, ocultando toda a lógica
envolvida no funcionamento do computador. Assim, foram criadas
as Graphicals User Interfaces (GUI) – interfaces gráficas com o usuário
–, pelo PARC da Xerox, que também desenvolveu o mouse. A aplicação
dessas interfaces se deu de maneira intensa na criação dos sistemas
operacionais. No Apple Macintosh (Figura 3), lançado em 1984, a GUI
estava embutida no sistema operacional, padronizando o aspecto de
todas as aplicações.
Nessa fase, podemos destacar sistemas operacionais,
como: o MS-DOS, lançado em 1981, pela Microsoft, para ser
utilizado no Personal Computer (PC) da IBM; o System OS, criado
pela Apple; e o Windows, também criado pela Microsoft,
com base em um ambiente gráfico, sobreposto ao MS-DOS.
No segmento de mini e superminicomputadores, destacaram-
-se os sistemas multiusuários, compatíveis com Unix e o VMS
da DEC.
Kevin chen2003/Wikimedia Commons
O ano de 1983 marcou o início de uma revolução no desenvolvimento
de software. Nesse ano, Richard Stallman, um ex-
-funcionário da IBM, ex-aluno de Harvard e desenvolvedor do
MIT, fundou o movimento de software livre, que buscava obter e
18 Sistemas Operacionais
garantir certas liberdades para os usuários, como o direito de executar,
estudar e modificar o software, além de a liberdade de distribuir cópias
desse software, com ou sem alterações. O lançamento do Projeto GNU,
também criado por Stallman, representou o marco de início do movimento
de software livre. O objetivo do projeto era criar um sistema
operacional, chamado GNU, com base em software livre. Esse projeto é
mantido, atualmente, pela Free Software Foundation (FSF) – Fundação
para o Software Livre – fundada por Stallman, em 1985.
O núcleo (core) do sistema operacional Linux começou com um
projeto particular de Linus Torvalds, inspirado no Minix, um pequeno
sistema operacional baseado no Unix, que foi criado por Andrew S.
Tanenbaum para fins acadêmicos.
Na década de 1980, foram desenvolvidos os sistemas operacionais
distribuídos, que trabalham com vários processadores. Esse conceito
foi popularizado pelo modelo cliente/servidor (client/server), em que
os clientes são os computadores de usuários que requisitam vários
serviços, e os servidores são computadores que executam os serviços
requisitados. Muitas vezes, os servidores eram dedicados a um tipo específico
de tarefa, como: renderização de gráficos, gerenciamento de
banco de dados ou hospedagem de páginas web.
A utilização de vários processadores, por parte dos sistemas distribuídos,
levou à necessidade de se melhorar os algoritmos de escalonamento
de processador, a fim de aprimorar o grau de paralelismo do sistema.
Os softwares de redes e as redes de computadores passaram a
ocupar um lugar de destaque nos sistemas operacionais, permitindo o
acesso a outros sistemas computacionais, independentemente do fabricante,
estado ou, até mesmo, país.
O multiprocessamento, isto é, a adição de mais processadores
ao computador, marcou o final dos anos 1980. Esse avanço veio para
atender à exigência das aplicações na realização de volumes de cálculos
gigantescos. Diante disso, os sistemas operacionais precisaram se
atualizar com novos mecanismos de controle e sincronismo, garantindo
a execução simultânea de mais de um programa ou, ainda, a execução
de um mesmo programa em processadores diferentes.
Entre as novas tecnologias que foram introduzidas, com a utilização
do multiprocessamento, garantindo o aumento de performance dos
computadores, podemos destacar:
Introdução aos sistemas operacionais 19
O uso dos processadores vetoriais ou processadores de matriz,
que implementavam um conjunto de instruções no formato de matrizes
unidimensionais de dados, chamadas vetores. Diferentemente dos
processadores escalares, cujas instruções operavam em itens de dados
individualmente, essa abordagem garantia um melhor desempenho
em simulações numéricas. Tendo surgido no início da década de 1970
e dominado os projetos de supercomputadores até os anos 1990, o
surgimento dos microprocessadores, com uma melhor relação entre
preço e desempenho, pôs fim à sua utilização.
O uso das técnicas de paralelismo, que permitem a execução
simultânea das tarefas.
Os sistemas operacionais desenvolvidos na década de 1990 foram
marcados por uma interface mais amigável com o usuário; as capacidades
de GUI, incluídas pela Apple no seu sistema operacional, e o
System OS, nos anos 1980, foram ampliados e melhorados. A possibilidade
de o usuário adicionar e remover componentes de hardware (plug-and-play
– ligar e usar) sem ter de reconfigurar o sistema operacional
tornaram-se reais. Os usuários passaram a autenticar seu acesso ao
sistema operacional, mantendo o seu perfil e permitindo a personalização
da interface, diferenciando-a dos demais usuários.
O núcleo do Linux, versão 0.02, foi lançado por Linus Torvalds em
1991. No ano seguinte, ele mudou a licença do núcleo do Linux para a
licença GPL (General Public License), criada pelo Projeto GNU, que foi,
inicialmente, utilizado por programadores, que interagiam por linhas de
comando. Atualmente, esse projeto é usado por grupos de desenvolvedores
que criam interfaces gráficas para diferentes distribuições GNU/Linux,
tornando-o um sistema operacional mais acessível. O projeto reúne
muitos programadores, de diversas partes do mundo, que contribuem
com o desenvolvimento do Linux, tornando o projeto um exemplo de
sucesso colaborativo no desenvolvimento de um sistema operacional.
O Linux é disponibilizado aos usuários por meio de várias distribuições,
como: Arch Linux, CentOS, Debian, Fedora Linux, Linux Mint,
openSUSE, Ubuntu etc. Os usuários corporativos fazem uso de distribuições
focadas nesse público, como Red Hat Enterprise Linux ou SUSE
Linux Enterprise Server. Uma distribuição Linux inclui: o núcleo Linux,
bibliotecas e utilitários, além de aplicações, como a suíte de escritório
denominada LibreOffice.
20 Sistemas Operacionais
Nos anos 2000, um número cada vez maior de computadores
passou a conseguir realizar paralelismo maciço, pois possuíam uma
grande quantidade de processadores, permitindo que partes independentes
das operações pudessem ser executadas em paralelo. Esse é
um conceito drasticamente diferente da computação sequencial das
fases iniciais das máquinas.
A computação em dispositivos móveis, como celulares e tablets, tornou-se
cada vez mais comum à medida que os processadores ficavam
menores e mais poderosos. O que era utilizado, inicialmente, para operações
como e-mail, navegação web e fotos, hoje é utilizado por aplicações
intensivas em recursos, como videoconferências. Apesar de limitados pelo
tamanho, os dispositivos móveis dependem da computação distribuída
para atender à sua demanda crescente de dados e processamento.
1.2 Ambientes de sistemas operacionais
Vídeo
Atualmente, os computadores são utilizados por usuários no seu
dia a dia, em computadores pessoais (desktops), notebooks, estações
de trabalho (workstations) ou dispositivos móveis (celulares e tablets);
ou corporativamente, por meio de servidores web, servidores de bancos
de dados, entre outros. Isso fez com que os sistemas operacionais
tivessem de se relacionar com um crescente número de recursos de
hardware, como: memória principal, discos de alta capacidade, dispositivos
periféricos etc. Somado a isso, do outro lado, há o sistema
operacional que se responsabiliza pela execução de uma infinidade de
aplicações (software) com diferentes finalidades (Figura 8).
Figura 4
Interação entre as aplicações e o sistema operacional
Aplicação
Aplicação
Aplicação
Espaço do usuário
Espaço do núcleo
Interface de chamada ao sistema
Componentes do SO
Fonte: Deitel; Deitel; Choffnes, 2005.
Introdução aos sistemas operacionais 21
Diante dessa diversidade de hardware e software, os sistemas operacionais
precisaram se adaptar a diferentes tipos de ambientes.
1.2.1 Sistemas embarcados
Segundo Stallings (2017), bilhões de sistemas operacionais são produzidos
anualmente. Os sistemas embarcados são computadores dedicados
ou embutidos, presentes em equipamentos que estão a nossa
volta, sendo chamados de computadores pervasivos ou ubíquos. Segundo
Li (2003), os usuários muitas vezes não percebem sua existência,
mas podemos encontrá-los nos eletroeletrônicos, hardwares de rede,
equipamentos hospitalares, automóveis etc.
Ao desenvolver sistemas operacionais para sistemas embarcados,
a grande preocupação está em gerenciar, de maneira eficiente, os recursos
disponíveis. Como estamos falando de dispositivos de pequeno
porte, a capacidade de armazenamento é limitada, levando à necessidade
da construção de sistemas operacionais que atendam aos serviços
necessários, com uma pequena quantidade de código. Outros pontos a
serem observados nesse tipo de sistema são: gerenciamento de energia
(bateria) e a necessidade de interfaces amigáveis para os usuários.
1.2.2 Sistemas de tempo real
Com a disseminação do uso de sistemas computacionais, as aplicações
com requisitos de tempo real tornaram-se cada vez mais comuns,
variando em relação à complexidade e às necessidades de garantia no
atendimento das restrições temporais. Assim, elas abrangem desde os
sistemas mais simples, como os controladores inteligentes embarcados
em utilidades domésticas (por exemplo, as lavadoras de roupa e
os DVD players), até os sistemas mais complexos, como os sistemas
militares de defesa e os de controle de tráfego aéreo. Mesmo sendo
caracterizadas como aplicações de tempo real, algumas delas apresentam
restrições de tempo mais rigorosas do que outras; entre elas, podemos
destacar os sistemas responsáveis pela respiração artificial de
pacientes, que estão internados em Unidades de Terapia Intensiva (UTI)
de hospitais, e os sistemas embarcados em robôs e veículos (automóveis,
aviões e sondas espaciais). Para exemplificar, o piloto automático
de uma aeronave deve ajustar, constantemente, a velocidade, altitude
e direção. Há, porém, aplicações que não apresentam restrições tão crí-
22 Sistemas Operacionais
ticas, como: os consoles de games, as teleconferências e as aplicações
de multimídia. Todas essas aplicações, que apresentam a característica
adicional de estarem sujeitas a restrições temporais, são agrupadas no
que é usualmente identificado como sistemas de tempo real.
Ao desenvolver sistemas operacionais para sistemas de tempo real, é
necessário assegurar que os processos respondam imediatamente aos
eventos críticos. Os sistemas de tempo real não críticos devem garantir
a execução das tarefas de tempo real com alta prioridade, mas sem
a garantia de que elas sejam concluídas a tempo ou que, até mesmo,
sejam concluídas. Já os sistemas de tempo real críticos garantem que
todas as tarefas serão concluídas a tempo. Muitas vezes, os sistemas de
tempo real são usados em sistemas de missão crítica, um sistema essencial
para a sobrevivência de uma empresa ou organização – ou seja,
quando esse tipo de sistema falha, as operações param e o negócio, por
sua vez, é afetado.
1.2.3 Sistemas críticos em negócios
Um sistema é considerado um sistema crítico em negócios quando
falha e pode resultar em perdas econômicas significativas para a
empresa que o utiliza. Podemos citar como exemplos os servidores
web e os servidores de bancos de dados.
Os sistemas operacionais garantem aos sites de comércio eletrônico
(e-commerce) um tempo de resposta rápido ao usuários que estão
comprando produtos pela internet; no uso corporativo, eles permitem
o compartilhamento de informações entre funcionários.
1.2.4 Máquinas virtuais
O conceito de máquina virtual (virtual machine – VM) permite a um
programa agir como um computador completo, com um sistema operacional
funcional. Assim, temos um computador sendo executado dentro
de outro computador. Para que isso aconteça, um programa cliente é utilizado
como uma camada de virtualização entre o sistema operacional do
computador hospedeiro e o sistema operacional do computador virtual.
A virtualização não é semelhante à emulação, em que os recursos
de um programa ou sistema são copiados e executados com o computador
hospedeiro. Na virtualização, a VM consegue operar de maneira
independente e isolada, conseguindo executar o sistema operacional,
Introdução aos sistemas operacionais 23
mesmo que esse seja incompatível com a arquitetura utilizada no computador
hospedeiro.
Livro
Leia o livro Sistemas
operacionais de tempo
real e sua aplicação em
sistemas embarcados
para encontrar uma
introdução teórica sobre
sistemas de tempo real,
além de exemplos de sua
aplicação.
DENARDIN, G. W.; BARRIQUELLO, C.
H. 1. ed. São Paulo: Blucher, 2019.
Figura 5
Diagrama de
uma máquina
virtual
Chamamos esse recurso de portabilidade – a capacidade de o
software ser executado em várias plataformas. Os recursos da máquina
virtual são gerenciados pelo sistema operacional dela. Uma das facilidades
oferecidas pela virtualização é permitir que várias instâncias de
sistemas operacionais diferentes possam ser executadas, simultaneamente,
em um computador hospedeiro. Dessa forma, podemos ter um
computador hospedeiro fazendo uso do sistema operacional Windows,
que executa VMs com diferentes versões de Linux.
As VMs fazem interface, via sistema operacional, com o hardware
do computador em que estão instaladas. Uma VM é capaz de criar
componentes de software que representam dispositivos físicos –
como processadores, memória, canais de comunicação, discos etc.
–, o que permite o compartilhamento de hardware entre vários
usuários (Figura 5).
A Java Virtual Machine (JVM) – máquina virtual java – é umas das VMs
mais utilizadas, servindo como fundamentação da plataforma Java. Ela
permite que as aplicações Java sejam executadas na versão correta de
JVM, independentemente da plataforma em que esteja instalada.
Empresas como a VMWare Software e Oracle fornecem máquinas virtuais,
baseadas na arquitetura Intel, permitindo a execução de sistemas
operacionais Linux e Windows, simultaneamente, em um só computador.
Aplicações
Aplicações
Aplicações
Linux
Windows Unix Camada de
hardware
virtual
Aplicações
Máquina Virtual
Sistema operacional
Aplicações
Software
Processador Memória Disco
Camada de
hardware
físico
Fonte: Deitel; Deitel; Choffnes, 2005.
24 Sistemas Operacionais
As VMs tendem a ser menos eficientes do que os computadores
reais, pois não acessam o hardware diretamente ou simulam
o hardware que não está conectado no computador hospedeiro, o
que aumenta o número de instruções de software requeridas para
cada ação de hardware.
1.3 Componentes e objetivos dos
Vídeo sistemas operacionais
Nesta seção, apresentaremos os principais componentes de um
sistema operacional, assim como os principais objetivos a serem alcançados
por um sistema operacional, isto é, suas características consideradas
essenciais.
1.3.1 Componentes centrais do sistema operacional
A interação do usuário com o sistema operacional é feita pelas
aplicações ativadas por ele ou por meio de uma aplicação especial
chamada shell, que atua como um interpretador de comandos. A implementação
dos interpretadores de comandos é feita pelas interfaces
de texto, que recebem os comandos dos usuários via teclado ou pela
interface gráfica (GUI), em que o usuário interage com o mouse, requisitando
a execução de serviços para o sistema operacional, como abrir
um aplicativo. Os sistemas operacionais modernos, que fazem uso de
GUI, possuem alternativas nas quais o usuário pode abrir um terminal
e digitar os seus comandos via teclado.
Segundo Deitel, Deitel e Choffnes (2005), o software que contém os
componentes centrais do sistema operacional chama-se núcleo (kernel).
Entre os componentes centrais do sistema operacional, estão:
Escalonador de processos
Sendo responsável pela decisão sobre o momento em que um processo
acessará a CPU, o escalonador de processos é um subsistema,
do sistema operacional, que faz uso de algoritmos de escalonamento
para estabelecer a lógica de sua execução. Ele pode variar de acordo
com o tipo de utilização do sistema operacional.
É necessário que exista atenção, por parte do sistema operacional,
para os processos que precisam de mais processamento, isto é, mais
Introdução aos sistemas operacionais 25
atividade da CPU, ocupando-a por mais tempo e possuindo pouca, ou
nenhuma, interação por parte do usuário. Como exemplo, temos a execução
de um programa de cálculo científico, no qual os parâmetros são
inseridos pelo usuário, o qual inicia a execução do programa, que demorará
um certo tempo para exibir o resultado, período em que fará
uso da CPU. O programa faz uso dos dispositivos de E/S somente na
fase inicial, quando o usuário inseriu os dados, e no momento final,
quando o sistema exibe o resultado do cálculo. Esse comportamento
de processo é chamado de processo orientado à CPU (CPU bound).
Pode parecer simples, mas o ato de teclar e, depois disso, o que foi
digitado aparecer na tela exige do sistema operacional um processo de
entrada/saída pela CPU, várias vezes, dentro de um pequeno intervalo
de tempo. Esse comportamento de processo é denominado processo
orientado à E/S (In/Out bound).
Os casos representados na figura a seguir mostram os diferentes
comportamentos de tais processos.
Figura 6
Comportamento de processos
Surto longo de uso de CPU
Surto longo de uso de CPU
Espera pela E/S
Tempo
(a) Processo CPU-bound ou orientado a CPU
(b) Processo I/O-bound ou orientado a E/S
Fonte: Novato, 2014.
Gerenciador de memória
Em sua grande maioria, os computadores fazem uso do conceito
de hierarquia de memória. No topo dessa hierarquia, encontram-se os
registradores, isto é, a memória que está dentro da CPU; eles são mais
rápidos e mais caros, o que ocasiona a sua pequena quantidade. São
seguidos, em uma quantidade maior, pela memória cache, que é muito
rápida, porém inferior à dos registradores. Depois dela, encontramos
26 Sistemas Operacionais
a memória principal (Random Access Memory), também conhecida
como memória RAM, em maior quantidade que a sua sucessora, porém
mais lenta. Por último, temos a memória de armazenamento em disco
(Hard Disk – HD), em uma quantidade muito maior que as anteriores,
mas considerada lenta quando comparada às demais.
Ao analisarmos o armazenamento de dados, em um sistema computacional,
podemos observar que ele ocorre em diversos níveis, ou
seja, em diferentes tipos de dispositivos, sempre levando em conta os
seguintes fatores:
a. o tempo de acesso ao dispositivo;
b. a velocidade com que a operação deverá ser realizada;
c. o custo da unidade de armazenamento;
d. a capacidade de armazenamento do dispositivo.
Tomando essa afirmação como base, ao realizar um projeto de sistema
operacional, devemos definir a quantidade de cada tipo de memória
que será necessária utilizarmos para garantir que o futuro sistema
seja, simultaneamente, eficiente e viável do ponto de vista financeiro.
Isso porque a velocidade, o preço e a capacidade de armazenamento
“andam de mãos dadas” quando falamos em memória. Quanto mais
rápida ela for, mais cara será, e menor será a sua capacidade de armazenamento.
A figura a seguir apresenta uma representação da hierarquia
de memória.
Velocidade:
Altíssima
Custo:
Altíssimo
Capacidade:
Pouquíssimo
Tamanho:
Muito pequeno
Energizado:
Sim
Velocidade:
Altíssima
Custo:
Altíssimo
Registradores
Capacidade:
Muito pouco
Tamanho:
Muito pequeno
Energizado:
Sim
Figura 7
Hierarquia de
organização da
memória
Velocidade:
Custo:
Capacidade:
Tamanho:
Energizado:
Velocidade:
Custo:
Capacidade:
Tamanho:
Energizado:
Fonte: Pendrive..., 2015.
Alta
Médio
Alta
Razoável
Sim
Baixa
Baixíssimo
Muito alta
Grande
Não
CPU cache
RAM
Dispositivos de
armazenamento
em massa
Introdução aos sistemas operacionais 27
Cabe ao gerenciador de memória comandar a hierarquia da memória,
isto é, controlar as partes da memória que estão em uso e as
que não estão, de modo a:
alocar a
memória aos
processos,
quando for
necessário;
liberar a
memória,
quando um
processo
terminar;
tratar do
problema de
swapping, isto
é, quando a
memória é
insuficiente.
Vyacheslavikus/Shutterstock
Desse modo, existem dois tipos de memória principal. Quando um
programa precisa alocar espaço em memória, ele faz uso da memória
lógica, que é a memória visível e manipulada pelos programas.
Essa memória, acessada pelos programas, existe na memória física,
implementada por Circuitos Integrados (CI). Isso ocorre graças à ação
de uma unidade de gerência de memória, que realiza a tradução dos
endereços lógicos em endereços físicos, permitindo que um programa
alocado na memória lógica possua um endereço de memória física correspondente.
Em geral, a memória lógica tem tamanho igual ou maior
que a memória física.
1.3.1.1 Gerenciador de E/S
O sistema operacional encontra no Gerenciador de E/S um parceiro
para realizar uma das principais e mais complexas atividades
no computador. Para isso, o gerenciamento de dispositivos de E/S é
estruturado em camadas, nas quais os níveis mais baixos ocultam as
caraterísticas de cada um dos dispositivos físicos das camadas superiores,
permitindo que as aplicações executadas pelo usuário atuem sem
conhecer a arquitetura do hardware utilizado pelas operações de E/S.
A existência de diferentes modelos de dispositivos de E/S, com características
diferentes entre si, levou os projetistas de sistemas operacionais
a desenvolverem uma camada chamada de subsistema de E/S,
que permite o isolamento desses dispositivos e sua ampla gama de
variações. Com isso, o sistema operacional ganha flexibilidade, conseguindo
realizar a comunicação entre as aplicações e qualquer tipo de
dispositivo de E/S.
28 Sistemas Operacionais
A comunicação do dispositivo de E/S com a camada do subsistema
de E/S é feita pela camada conhecida como device driver, que se responsabiliza
pelos aspectos técnicos dessa comunicação, como a velocidade
da operação, a unidade de transferência, a representação dos dados e
os tipos de operações a serem realizados.
Essas camadas são divididas em dois grupos: o primeiro grupo
é responsável por permitir a visualização de todos os dispositivos
de modo único, sem distinção; já o segundo grupo atua de maneira
específica para cada um dos dispositivos. Em sua maioria, as
camadas atuam de modo independente dos dispositivos de E/S
(Figura 8).
Figura 8
Camadas da gerência de dispositivos
Processo
Software
Modo kernel Modo usuário
Operações de E/S
Sistema de
arquivos
Subsistema de E/S
Device drivers
Independente
do dispositivo
(a)
Hardware
Controladores
Dependente
do dispositivo
(b)
Dispositivo de E/S
Representação das camadas que realizam o gerenciamento dos dispositivos de E/S.
Fonte: Machado; Maia, 2013.
Introdução aos sistemas operacionais 29
Figura 9
Subsistema (system calls) de E/S
Comandos
de E/S
Fonte: Machado; Maia, 2013.
Figura 10
Device driver
Aplicação
System calls de E/S
Rotinas de E/S
Device drivers
Dispositivos de E/S
Bibliotecas
O subsistema de E/S (system calls) desempenha
um papel muito importante, pois busca simplificar
a interação entre o usuário e as aplicações, isolando
a complexidade dos dispositivos de E/S de suas
operações, que são diferentes entre cada um dos
dispositivos, e sua relação com as demais camadas
– por exemplo, sistemas de arquivos, banco de dados
e aplicações (Figura 9).
As rotinas de E/S são um conjunto de rotinas especiais
que cuidam dos detalhes das operações de leitura
e escrita a serem realizadas pelo sistema operacional,
como o passo a passo que deve ser feito na gravação
de um arquivo. Isso acontece sem que o usuário e a
aplicação se preocupem com essa tarefa, que passa a
ser de responsabilidade do subsistema de E/S.
A comunicação do subsistema de E/S com os dispositivos
é feita por meio dos controladores de E/S, o
device driver (ou somente driver). Cabe ao subsistema
de E/S gerenciar as funcionalidades de todos os
dispositivos de E/S ligados ao computador, enquanto
o driver se responsabiliza pelas particularidades
de cada um dos dispositivos (Figura 9).
Driver de
impressora
Controlador
de impressora
Fonte: Machado; Maia, 2013.
Processo
Subsistema de E/S
Driver de
disco
Controlador
de disco
Driver de
fita
Controlador
de fita
Os dispositivos de E/S enviam comandos gerais
de leitura e escrita para os seus device drivers, os
quais traduzem esses comandos para comandos específicos
de leitura e escrita, que poderão ser executados
pelo controlador de E/S do dispositivo.
Os controladores de E/S são os dispositivos de
hardware responsáveis por interagir com os dispositivos
de E/S. Existe um controlador de E/S para cada
tipo de dispositivo de E/S, por exemplo, disco rígido,
impressora, webcam etc. A comunicação entre os
dois é possibilitada pelo device driver, que faz a tradução
das instruções recebidas dos dispositivos e as
converte para um padrão compreensível pelo controlador.
Os controladores podem estar acoplados à
CPU por meio de uma placa ou implementados na
própria placa do processador.
30 Sistemas Operacionais
No sistema operacional Windows, da Microsoft, os device drivers
são desenvolvidos com base em um padrão chamado Windows Driver
Model (WDM), responsável por definir um conjunto de características e
funções a serem oferecidas por um driver. Esse padrão é homologado
pela Microsoft, permitindo que o sistema operacional possa efetuar tarefas,
como: suporte ao plug-and-play (ligar e usar), acesso a múltiplos
processadores, gerência de energia dos dispositivos e interação com os
objetos do sistema operacional (Figura 11).
Figura 11
Janela do Device Manager (gerenciador de dispositivos) do Windows
No sistema operacional Unix, o gerenciador de E/S foi desenvolvido
de modo integrado ao sistema de arquivos, permitindo acesso aos
dispositivos de E/S por meio de arquivos especiais, que podem ser
acessados como qualquer outro arquivo pelas system calls de leitura
e gravação, enviando o mesmo dado para diferentes tipos de saída e
garantindo às system calls de E/S a uniformidade na manipulação de
Introdução aos sistemas operacionais 31
qualquer tipo de dispositivo de E/S. Esses arquivos especiais são armazenados
no diretório do sistema operacional Unix.
Em suas versões mais recentes, os sistemas operacionais Unix/
Linux passaram a permitir que os drivers dos dispositivos de E/S
pudessem ser acoplados ao núcleo com o sistema operacional em funcionamento,
sem a necessidade de se compilar e gerar um novo kernel
ou mesmo efetuar o reboot (reinicialização) do sistema operacional
para reconhecê-lo.
A transferência dos dados, recebidos pelos dispositivos de E/S, para
o sistema operacional é feita pelos controladores de E/S por meio de
blocos de informação. Os dispositivos de E/S são responsáveis pela
comunicação do computador com o mundo externo, sendo classificados
como dispositivos de entrada de dados, saída de dados ou ambos
(entrada e saída).
1.3.1.2 Gerenciador de comunicação interprocessos (IPC)
Para garantir a interdependência dos processos, os sistemas operacionais
implementaram alguns mecanismos, com os quais os processos
são executados em cápsulas autônomas, de modo que sua execução
não afete a dos demais. O hardware também faz sua parte, oferecendo
proteção à memória e garantindo que um processo não ocupe o mesmo
espaço endereçado ao outro.
Os processos, entretanto, interagem e cooperam na execução de
tarefas. Em muitos casos, os processos precisam trocar informação de
maneira controlada para:
a. dividir tarefas e aumentar a velocidade de processamento;
b. aumentar a capacidade de transferência de dados (rede);
c. atender a requisições simultâneas.
Para atender a essa demanda, o sistema operacional fornece mecanismos
que permitem aos processos se comunicarem uns com os
outros por meio do IPC (Inter-Process Communication), um conjunto
de mecanismos de troca de informação entre múltiplas threads de um
ou mais processos. Os mecanismos de IPC permitem ao sistema operacional
implementar canais de comunicação (implícitos ou explícitos)
entre os processos.
32 Sistemas Operacionais
Para realizar sua tarefa com eficiência, o IPC precisa se preocupar
com a coordenação da comunicação, realizando a sincronização do
processo, na qual o processo emissor precisa informar que um dado
foi transmitido e o processo receptor precisa saber que o dado enviado
está disponível, informando aos dois quando podem realizar
uma nova comunicação.
Os processos podem se comunicar das seguintes formas: internamente,
quando dois módulos de um mesmo processo se comunicam;
entre dois processos diferentes, em um mesmo computador;
ou externamente, quando dois processos em computadores diferentes
se comunicam.
Para realizar sua tarefa, o IPC pode fazer uso dos seguintes modelos
de comunicação.
a. Difusão (broadcast): quando o receptor envia a mesma
mensagem para um grupo de receptores, sem saber quem são
eles.
b. Produtor-consumidor: quando existe somente um emissor e
um receptor, com a comunicação unidirecional entre eles.
c. Cliente-servidor: quando o cliente, que pode ser um
computador, programa ou processo, solicita uma requisição
para um servidor, que também pode ser um computador,
programa ou processo.
d. Peer-to-Peer (P2P): quando cada um dos nós (computadores,
programas ou processos) que participam da comunicação
atuam como servidores ou clientes.
e. Caixa de correio (mailbox): quando a comunicação entre
o emissor e o receptor funciona como uma caixa de correio,
na qual o receptor não escolhe o emissor que lhe escreveu
a mensagem. Pode ser classificada em dois tipos: a escrita
não bloqueante, quando a capacidade de armazenamento da
caixa de correio é ilimitada; ou de leitura bloqueante, quando
a caixa de correio está vazia.
f. Diálogo: quando há servidores exclusivos para cada cliente,
unidos por um canal de comunicação dedicado somente a eles,
que será desligado quando a comunicação entre eles acabar.
Introdução aos sistemas operacionais 33
1.3.1.3 Gerenciador de sistemas de arquivos
O gerenciador de sistemas de arquivos é responsável pelo gerenciamento
dos arquivos e das operações que esses realizam, bem como
pela segurança no seu acesso, garantindo que um usuário não consiga
acessar um arquivo que pertence a outro usuário sem ter autorização
para fazê-lo. Ele também é responsável por compartilhar arquivos entre
os processos e usuários.
O gerenciador de sistemas de arquivos acaba desempenhando o
papel mais visível para o usuário do sistema operacional, pois está
sempre manipulando os arquivos, criando ou editando os seus documentos
ou executando os aplicativos, que, para o computador, também
são arquivos.
Podemos definir um arquivo como sendo um conjunto de informações,
dados ou instruções relacionados logicamente. As visões são
distintas, o usuário enxerga diferentes tipos de arquivos; mas, para o
sistema operacional, um arquivo é um conjunto de registros definido
pelo sistema de arquivos.
O conteúdo desse arquivo vai influenciar a forma como ele será processado,
por exemplo:
a. um arquivo executável é composto de instruções em linguagem
de máquina, que faz com que ele seja executado pelo sistema
operacional;
b. um arquivo de dados é constituído por dados estruturados ou
não, que são lidos pelo sistema operacional;
c. um arquivo de multimídia pode possuir imagem, áudio, som,
vídeo etc., que será disponibilizado pelo sistema operacional para
o usuário.
O sistema operacional pode armazenar os arquivos em diferentes
dispositivos físicos, como: fitas magnéticas, discos magnéticos, discos
ópticos, entre outros. Para que isso aconteça, o sistema operacional
dever criar um isolamento do tipo de dispositivo físico utilizado, permitindo
que o sistema operacional consiga realizar a manipulação dos
arquivos em diferentes dispositivos de armazenamento.
Para que possa ser identificado pelo sistema operacional, um arquivo
precisa de nome. Para isso, o sistema operacional possui algu-
34 Sistemas Operacionais
mas regras particulares a serem seguidas na definição do nome do
arquivo, por exemplo: o tamanho do nome, os caracteres a serem usados,
a distinção ou não de caracteres maiúsculos ou minúsculos, entre
outras. A extensão é utilizada por alguns sistemas operacionais com
parte do nome do arquivo; seu papel é identificar o tipo de conteúdo
do arquivo. Para exemplificar, se pensarmos no sistema operacional
Windows, quando visualizamos um arquivo com extensão .docx, sabemos
que ele pertence ao Word. Por outro lado, se vemos um arquivo
com extensão .xlsx, sabemos que ele pertence ao Excel.
Os diretórios surgem como uma forma de organizar os arquivos
(Figura 12), e são criados pelo gerenciador de sistemas de arquivo.
Eles são uma estrutura de dados, no formato de árvore, que conterão
elementos associados aos arquivos. Esses elementos vão possuir informações,
como a localização física do arquivo, seus nomes, a forma de
organização do diretório etc. Uma regra é válida para todos os sistemas
operacionais: você não pode armazenar dois arquivos com o mesmo
nome em um mesmo diretório.
Figura 12
Representação visual de um sistema de arquivos, com diretórios e arquivos
Quando o usuário abre um arquivo no seu computador, o gerenciador
de sistemas de arquivo busca os seus dados na estrutura
de diretórios e efetua o armazenamento da sua localização e do
seu nome em uma tabela da memória principal do computador, a
qual mantém uma listagem de todos os arquivos abertos, trazendo
performance à operação de acesso a esses arquivos. Esses registros
permanecerão lá, enquanto os arquivos estiverem sendo utilizados
Introdução aos sistemas operacionais 35
e não tiverem sido fechados; quando isso ocorre, os seus registros
na tabela também são liberados.
A forma mais simples de se implementar uma estrutura de diretórios
é conhecida como nível único, em que não existem subdiretórios,
apenas o diretório raiz, contendo todos os arquivos. Apesar de
simples, esse modelo é muito limitado e não é recomendado quando
precisamos implementar segurança no acesso aos arquivos.
Para controlar a criação de arquivos, o sistema operacional precisa
realizar o gerenciamento do espaço livre, isto é, identificar quais
são os blocos e setores em disco que estão disponíveis para a criação
dos arquivos. O sistema consegue essa informação fazendo uma
consulta à estrutura de dados em memória – uma tabela em que o
sistema operacional consegue identificar os blocos livres que poderão
ser alocados pelo novo arquivo. Ao fazer isso, esse espaço é removido
da tabela para evitar que seja alocado por um outro arquivo.
De maneira análoga, quando o usuário apaga um arquivo, os blocos
em que ele estava armazenado são liberados e incluídos novamente
na tabela de blocos livres.
Outra preocupação do gerenciador de sistemas de arquivos é o
gerenciamento do espaço alocado por esses arquivos, pois, com o
decorrer do tempo, os arquivos mudam e a necessidade de espaço
de armazenamento também. A importância dessa atividade se dá
por estarmos falando de uma operação que pode sofrer influência
direta da ação dos usuários, em um recurso com limitação de tamanho,
como ocorre, por exemplo, com o disco rígido.
Além disso, faz parte das atividades do gerenciador de sistemas
de arquivos permitir o compartilhamento desses arquivos
entre usuários e processos, garantindo que somente usuários e
processos devidamente autorizados tenham acesso aos arquivos
compartilhados.
O sistema operacional implementa a proteção de acesso fazendo
uso do controle de concessão de operações, isto é, leitura, gravação,
execução e, em alguns momentos, exclusão. Os sistemas operacionais
Unix/Linux permitem a ampliação das concessões de direitos
aos usuários que participam do mesmo grupo daquele que está concedendo
o direito ou, até mesmo, a outros usuários que não fazem
parte do grupo do dono do arquivo.
36 Sistemas Operacionais
1.3.2 Objetivos do sistema operacional
De acordo com a evolução dos sistemas operacionais, os usuários
passaram a considerar certas características como essenciais. Segundo
Deitel, Deitel e Choffnes (2005), os objetivos a serem alcançados pelos
sistemas operacionais são:
a. Eficiência: característica que mede a capacidade de um sistema
operacional em oferecer o máximo de serviços a diferentes
aplicações, no menor espaço de tempo.
b. Robustez: característica que permite ao sistema operacional ser
tolerante a falhas e confiável; caso ocorra um erro de aplicação
(de software ou hardware), o sistema operacional buscará
minimizar a perda do trabalho realizado, tentando evitar danos
ao hardware do computador.
c. Escalabilidade: característica que permite ao sistema operacional
fazer uso de recursos à medida que eles vão sendo acrescentados
ao computador, sendo muito útil quando falamos de sistemas
multiprocessados.
d. Extensibilidade: essa característica garante que o sistema
operacional se adapte bem ao uso de novas tecnologias, bem
como que execute tarefas diferentes daquelas para as quais
foi projetado. Dessa forma, a extensibilidade proporciona o
aumento da flexibilidade do sistema operacional. Ao possibilitar
que os usuários adaptem ou evitem o sistema operacional, os
sistemas operacionais extensíveis possibilitam, em particular,
que os usuários ajustem o comportamento do sistema para
obterem um maior desempenho em casos específicos.
e. Portabilidade: a portabilidade garante que o sistema operacional
opere em muitas configurações de hardware. A portabilidade de
aplicações também é importante, pois o desenvolvimento das
aplicações (software) custa caro; portanto, a mesma aplicação
deve ser executada em uma variedade de configurações de
hardware, reduzindo os custos de desenvolvimento.
f. Segurança: a segurança em um sistema operacional impede que
os usuários e/ou softwares acessem os serviços ou recursos sem a
devida autorização. Os mecanismos que implementam as políticas
de segurança do sistema operacional são chamados de proteção.
Introdução aos sistemas operacionais 37
g. Interatividade: a interatividade permite que as aplicações
(software) respondam, rapidamente, às solicitações dos usuários
ou aos eventos do sistema operacional.
h. Usabilidade: a usabilidade concede ao sistema operacional o
potencial de atender a uma base significativa de usuários. Esses
sistemas operacionais, geralmente, apresentam uma interface
gráfica (GUI) amigável, fácil de se utilizar. Sistemas operacionais,
como Linux, Windows e MacOS, são caraterizados como
utilizáveis, pois suportam muitas aplicações e fornecem uma
interface-padrão para o usuário; isso não ocorre com sistemas
operacionais acadêmicos ou experimentais, portanto, eles não
são considerados utilizáveis.
1.4 Arquitetura de sistemas operacionais
Vídeo As diferentes arquiteturas dos sistemas operacionais são resultado
da necessidade de os computadores atenderem a diversos serviços
e interagirem com os mais variados recursos de hardware e software
para a execução das suas atividades.
1.4.1 Arquitetura monolítica
Figura 13
Arquitetura de
sistema operacional
de núcleo
monolítico
Os primeiros sistemas operacionais, como OS/360, CP/M, MS-DOS
e as versões inicias do Linux, faziam parte da arquitetura monolítica
(Figura 13) – em que os componentes eram compilados em módulos
separados e depois eram unidos (linkados) em um único programa
executável, denominado núcleo (core) –, sendo, também, chamada de
arquitetura de sistema operacional de núcleo monolítico. Os módulos do
sistema operacional, os quais fazem uso desse tipo de arquitetura, eram
carregados em memória e interagiam entre si por meio de funções.
Aplicações
Interface de chamada ao sistema
Núcleo
GM
E/S
EP
GR
CEP
...
SA
Espaço do usuário
Espaço do núcleo
GM – EP – CEP – SA – E/S – GR - ...
GM= Gerenciador de memória
EP = Escalonador de processador
CEP = Comunicação entre processos
SA = Sistema de arquivos
E/S= Gerenciador de Entrada/Saída
GR = Gerenciador de rede
Fonte: Deitel; Deitel; Choffnes, 2005, p. 20.
38 Sistemas Operacionais
A manutenção e a compreensão do código-fonte desse tipo de sistema
são complicadas, pois é difícil isolar a fonte de problemas e de
outros erros. Além disso, como todo o código é executado com acesso
irrestrito ao sistema, os sistemas de núcleo monolítico são particularmente
suscetíveis a danos provocados por códigos sujeitos a erros ou
mal-intencionados.
1.4.2 Arquitetura em camadas
Buscando atender à evolução e complexidade das atividades realizadas
pelos sistemas operacionais, surgiu a arquitetura em camadas
(Figura 14), na qual o sistema operacional é composto de níveis ou
camadas que se comunicam entre si. As camadas inferiores prestam
serviço às camadas de nível superior, fazendo uso de uma interface, o
que oculta para a camada de cima a sua implementação.
O isolamento entre as camadas representa uma vantagem no uso
desse tipo de arquitetura, garantindo segurança e proteção às camadas
mais internas, onde está localizado o núcleo do sistema operacional.
Porém, o desempenho do sistema é afetado negativamente pela troca
de modo de acesso. Quando um serviço é solicitado para a camada do
kernel, o sistema operacional precisará passar por várias camadas até
chegar ao seu destino, realizando diversas trocas do modo de acesso durante
o trajeto, o que constitui uma desvantagem para essa arquitetura.
Figura 14
Camadas do sistema
operacional
Usuário
Espaço do usuário
Espaço do núcleo
Camada 4
Camada 3
Aplicações do usuário
Gerenciamento de E/S
Camada 2
Camada 1
Interpretador de mensagem
Gerenciamento de memória
Hardware
Camada 0
Alocação de processador e escalonamento de
processo hardware
Fonte: Deitel; Deitel; Choffnes, 2005, p. 20.
Introdução aos sistemas operacionais 39
1.4.3 Arquitetura de micronúcleo (MicroKernel)
A arquitetura de micronúcleo (MicroKernel) busca tornar o núcleo
do sistema operacional o menor e mais simples possível (Figura 15).
Nessa arquitetura, os componentes do sistema operacional são disponibilizados
como serviços. Cada serviço oferece um conjunto de funções,
como: gerência de arquivos, gerência de processos, gerência de
memória etc.
Quando uma aplicação do usuário solicita um serviço, realiza-se
uma requisição ao processo responsável pelo serviço. A aplicação que
solicita o serviço é chamada de cliente, e o processo que responde à
solicitação é denominado servidor. O núcleo do sistema se limita a executar
a comunicação entre cliente e servidor. Portanto, temos um núcleo
muito mais simples.
Figura 15
Arquitetura de sistema operacional de micronúcleo
Aplicações
Interface de chamada ao sistema
Sistema de arquivos Escalonador de processos Gerenciador de dispositivos
...
Espaço do usuário
Espaço do núcleo
CEP
Núcleo
Gerenciamento de memória
Sincronização
Fonte: Deitel; Deitel; Choffnes, 2005.
A arquitetura de micronúcleo exibe um alto grau de modularidade,
o que a torna extensível, portável e escalável. Com micronúcleos,
os processos executam suas funções em modo usuário, ou
seja, não têm acesso a instruções privilegiadas e não têm acesso
aos componentes do sistema. Apenas o núcleo executa em modo
kernel. Isso garante que, caso ocorra algum erro em um processo,
o sistema não ficará completamente comprometido, aumentando
a sua disponibilidade.
40 Sistemas Operacionais
São exemplos de sistemas operacionais, que fazem uso desse tipo
de arquitetura: o GNU Hurd, desenvolvido pelo Projeto GNU, Minix e
QNX e utilizado em sistemas embarcados; e o L4, desenvolvido por Jochen
Liedtke, cientista alemão da computação, que atuou na pesquisa
de microkernels.
1.4.4 Sistema Operacional de Redes (SOR)
Para complementar as funções básicas de um sistema operacional,
permitindo que elas possam ser utilizadas em recursos compartilhados
em rede, o sistema operacional faz uso do Sistema Operacional de
Redes (SOR) (Figura 16). Isso ocorre por meio da interação do Sistema
Operacional Local (SOL) com o SOR, que permite a utilização de recursos
do computador local e os recursos da rede. De maneira simples, o
SOL faz uma requisição para a rede, e essa requisição é recebida pelo
SOR, o qual a encaminha para um programa de comunicação, que vai
buscar na rede quem poderá atendê-la.
O modelo utilizado pelo SOR é o cliente/servidor, em que o computador
local atua como cliente, solicitando um serviço para a rede, na
qual um outro computador ou dispositivo atuará como servidor, atendendo
à demanda solicitada.
Figura 16
Modelo de sistema operacional de rede cliente/servidor
Servidor
Servidor
Servidor
Disco
Processador
Hub
Cliente
Cliente
Cliente
Fonte: Deitel; Deitel; Choffnes, 2005.
Cliente
Cliente
Introdução aos sistemas operacionais 41
Entre os tipos de arquitetura SOR, podemos destacar: Peer-to-Peer
(P2P), na qual as máquinas interligadas atuam como clientes e servidoras;
cliente/servidor com servidor dedicado, em que há uma máquina
que atua como servidora, mas executa atividades locais; e cliente/servidor
com servidor não dedicado, na qual a máquina servidora atende
às requisições dos clientes.
Os servidores podem ter diferentes atuações, como: servidores de
arquivos, nos quais são armazenados arquivos de dados ou programas
a serem compartilhados entre os usuários de uma rede; servidores de
bancos de dados, em que são armazenados dados que serão cadastrados
ou consultados pelos usuários da rede, fazendo uso de uma interface
ou via web; servidores de impressão, utilizados para gerenciar
as impressoras conectadas na rede, facilitando o roteamento dos documentos
a serem impressos ou controlando as cotas de impressão por
usuário em um período de tempo; servidores de comunicação, responsáveis
pela distribuição da informação na rede, como correio eletrônico
(e-mail), web, FTP (File Transfer Protocol) etc., podendo, também,
ser utilizados para gerenciar o acesso remoto dos usuários da rede;
ou servidores de gerenciamento, que atuam no controle de acesso
dos usuários, no controle de tráfego da rede e, em alguns casos, atuam
como firewall, isto é, um dispositivo de hardware ou software que aplica
políticas de segurança a um determinado ponto da rede.
1.4.5 Sistema operacional distribuído
Ampliando o conceito de sistema operacional de rede, surge-se o
conceito de sistemas distribuídos, em que encontramos um conjunto de
computadores ligados a uma rede e independentes entre si, os quais
atuam de modo que dão ao usuário a impressão de que são um sistema
único e integrado.
As tarefas nos sistemas distribuídos são divididas entre os computadores
que os compõem, sem a interferência do usuário; tudo ocorre
de maneira transparente. Isso os diferencia do sistema operacional
de rede, em que as decisões de processamento e armazenamento são
realizadas pelo usuário.
São consideradas características do sistema distribuído: a capacidade
de realizar tarefas simultaneamente (concorrência); a capacidade
42 Sistemas Operacionais
de adicionar novos computadores, aumentando o processamento ou
armazenamento (escalabilidade); o uso de mensagens para trocar informações
entre os programas e as estações de trabalho; e, por fim,
caso uma estação de trabalho pare de funcionar, não haverá comprometimento
do serviço, pois outra estação irá assumir as funções desempenhadas
pela máquina que parou de funcionar.
Com base nessas características, podemos concluir que os objetivos
finais da utilização de um sistema operacional distribuído são o acesso
aos recursos, a transparência, a abertura e a escalabilidade.
CONSIDERAÇÕES FINAIS
Iniciamos este capítulo mostrando que a criação e o desenvolvimento
dos sistemas operacionais estão intimamente ligados à evolução do
computador, do desenvolvimento de software e da crescente demanda
de performance e segurança. Os diferentes tipos de aplicações fizeram
com que os sistemas operacionais tivessem de se adaptar a diferentes
ambientes, atendendo a requisições específicas de hardware e software.
Vimos, também, que o núcleo (kernel) do sistema operacional faz uso
de componentes (subsistemas) para realizar as tarefas mais importantes;
tarefas essas que cumprem as características necessárias de um sistema
operacional. Por fim, encerramos o capítulo apresentando as possíveis
arquiteturas que um sistema operacional pode usar, bem como os exemplos
de sistemas operacionais que as utilizam.
ATIVIDADES
1. Por que os computadores da primeira fase não usavam sistemas
operacionais?
2. Quais tecnologias foram responsáveis pela segunda fase de computadores?
Quais foram os ganhos obtidos com elas?
3. Quais são os diferenciais da série 360 da IBM?
4. Qual conceito foi incorporado aos sistemas operacionais TSS, Multics e
CP/CMS? Qual foi o benefício que esse conceito trouxe?
5. O que é um sistema crítico em negócios?
Introdução aos sistemas operacionais 43
REFERÊNCIAS
DEITEL, H. M.; DEITEL, P.; CHOFFNES, D. Sistemas operacionais. 3. ed. Trad. de Arlete Simille
Marques. São Paulo: Pearson, 2005.
LI, Q. Real-time Concepts for Embedded Systems. 1. ed. Routledge, 2003.
MACHADO, F. B.; MAIA, L. P. Arquitetura de Sistemas Operacionais. 5. ed. São Paulo: LTC,
2013.
NOVATO, D. Sistemas Operacionais - O que é escalonamento de processos? Oficina da
net, 22 maio 2014. Disponível em: https://www.oficinadanet.com.br/post/12781-sistemasoperacionais-o-que-e-escalonamento-de-processos.
Acesso em: 26 maio 2020.
PENDRIVE x HD x Nuvem: Como usar a hierarquia de memória para gerenciar seus
arquivos. Por que não um “blog”, 2015. Disponível em: http://stonesjunior.blogspot.
com/2015/12/hierarquia-de-memoria-e-suas-aplicacoes.html. Acesso em: 26 maio 2020.
STALLINGS, W. Arquitetura e organização de computadores. 10. ed. São Paulo: Pearson
Prentice-Hall, 2017.
44 Sistemas Operacionais
2
Interação do sistema
operacional com
hardware e software
Além de cumprir suas tarefas, o sistema operacional precisa
se relacionar com várias outras partes. Ele atende às solicitações
do usuário recebendo e devolvendo dados. Ele converte
tais solicitações em tarefas, que serão executadas pelo computador,
respeitando os mais diferentes projetos de arquitetura.
Ademais, o sistema operacional precisa estender esse relacionamento
a uma infinidade de dispositivos e de diversos propósitos,
os quais são acoplados ao computador e auxiliam o usuário
na realização das suas operações.
Neste capítulo, abordaremos a relação dos sistemas operacionais
com os arquivos e diretórios, que são as estruturas mais
utilizadas pelos usuários no manuseio do computador; a evolução
da programação, a qual passou de linguagem de máquina
para as linguagens de alto nível e começou a fazer uso de compiladores
e interpretadores para aumentar a produtividade dos
desenvolvedores; o uso de firmwares e middlewares, facilitando
a comunicação dos dispositivos e programas com o sistema operacional
e o computador. Estudaremos, também, os hardwares,
as suas diferentes arquiteturas e como eles interagem entre si
e com o sistema operacional; o processador, o seu projeto, o
desempenho e o uso de multiprocessadores; a memória, a sua
hierarquia e as diferenças de custo e desempenho; o uso de
discos e fitas, como forma de armazenamento de baixo custo;
os barramentos, responsáveis pela comunicação entre os componentes
do computador; e, finalmente, os dispositivos de E/S,
que são acoplados ao computador, fazendo com que o sistema
operacional os reconheça e se comunique com eles.
Interação do sistema operacional com hardware e software 45
2.1 Arquivos e diretórios
Vídeo Segundo Tanenbaum (2015), arquivo é um mecanismo de abstração
que oferece meios de armazenar informações no disco e de lê-las depois.
Essa abstração permite ao sistema operacional ocultar do usuário
onde realmente essa informação está armazenada, bem como a forma
com que esse processo ocorre.
Analisando os diferentes sistemas operacionais, as características
mais comuns, quanto à nomeação dos arquivos, são:
O tamanho
do nome
Alguns sistemas operacionais aceitam arquivos com nomes de até
8 caracteres e outros suportam até 255 caracteres.
O uso de
caracteres
especiais
Alguns sistemas operacionais suportam o uso de caracteres
especiais, outros não.
Pure Imagination/Shutterstock
Sistemas
operacionais
A distinção de
caracteres em
letra maiúscula
Alguns sistemas operacionais, como o UNIX, suportam a distinção
em letras maiúsculas, outros não, como o MS-DOS.
O uso de
extensão
Para muitos sistemas operacionais o uso de extensão é opcional; o
MS-DOS permitia arquivos com nomes de um a oito caracteres e a
extensão com um a três caracteres; no UNIX, a extensão é opcional,
seu tamanho é definido pelo usuário e um arquivo pode ter mais de
uma extensão, como o arquivo arquivohtml.tar.gz, o qual passou por
compactação dupla, a primeira pelo compactador TAR e a segunda pelo
compactador GZIP.
O valor da
extensão
Para alguns sistemas operacionais, a extensão do arquivo possui valor, por
exemplo, um arquivo.txt, para o Windows, será reconhecido como um arquivo
de texto e será aberto por um aplicativo vinculado a essa extensão; para o
UNIX, como a extensão pode ser atribuída livremente pelo usuário, não existe
essa relação de extensão com o conteúdo do arquivo nem com aplicativo
responsável por executá-lo ou abri-lo.
46 Sistemas Operacionais
A maneira mais simples de se armazenar um arquivo em um sistema
operacional é considerá-lo uma sequência de bytes, na qual
o sistema operacional não se preocupa com o conteúdo do arquivo,
deixando a responsabilidade da sua identificação com o usuário. Essa
estratégia é utilizada por sistemas operacionais como UNIX e Windows.
Uma outra abordagem é transformar o arquivo em uma sequência de
registros de tamanho fixo, assim, quando uma alteração ocorre, o
sistema operacional identifica qual registro foi alterado e o reescreve.
Essa forma de armazenamento era utilizada por sistemas operacionais
no tempo das leitoras de cartão perfurado. Por fim, um arquivo pode
ser armazenado no formato de uma árvore de registros, que é ordenada
por campos-chave, contidos dentro de cada registro. Essa forma
de armazenamento é utilizada em computadores de grande porte,
para processamento de dados comerciais. Os três modos de armazenamento
mencionados são apresentados na Figura 1.
Figura 1
Três tipos de arquivos: sequência de bytes (a), sequência de registros (b), árvore (c)
1 Byte
1 Registro
Formiga Raposa Porco
Gato Vaca Cachorro Cabra Leão Coruja Pônei Rato Minhoca
Galinha
(a) (b) (c)
Íbis
Ovelha
Fonte: Tanenbaum, 2015, p. 160.
Os sistemas operacionais UNIX e Windows suportam o armazenamento
de arquivos regulares, os quais contêm informações
do usuário, e de diretórios, arquivos que mantém a estrutura do
sistema de arquivos. O UNIX também suporta arquivos especiais
de caracteres, utilizados para se comunicar com dispositivos de
E/S; e os arquivos especiais de blocos, utilizados para se comunicar
com os discos. De acordo com Tanenbaum (2015), cabe a todo
sistema operacional reconhecer pelo menos um tipo de arquivo, os
seus próprios arquivos executáveis.
Interação do sistema operacional com hardware e software 47
Glossário
Byte (binary term): uma
unidade computacional que é
constituída por oito bits.
Quando analisamos as diferentes possibilidades de acesso aos
arquivos, percebemos que os sistemas operacionais começaram fazendo
uso do acesso sequencial, no qual se efetuava a leitura dos
bytes ou registros, do início ao fim, sem realizar saltos durante a
leitura. Esse tipo de leitura fica clara quando fazemos uso da fita
magnética como dispositivo de E/S. Com o surgimento do armazenamento
em disco, os sistemas operacionais começaram a fazer
acesso aleatório aos arquivos, assim, não havia mais a necessidade
de se realizar o acesso sequencial à informação. Isso trouxe ganhos
muito grandes para as aplicações, por exemplo, ao procurar dados
de um funcionário de uma empresa, não havia mais a necessidade
de percorrer todos os registros até encontrá-lo.
Para ter um melhor controle, os sistemas de arquivos fazem
uso, em geral, de diretórios ou pastas, que em muitos sistemas
também são arquivos (TANENBAUM, 2015).
A forma mais simples de utilização de diretório é quando o sistema
operacional faz uso de somente um para armazenar todos
os seus arquivos, sendo este chamado de diretório-raiz, conforme
demostrado na Figura 2. Isso era possível, pois os computadores
pessoais antigos não eram multiusuários, sendo que a utilização
do diretório-raiz (isto é, diretório único), armazenando todos os arquivos
de vários usuários, resultaria em um grande esforço para
controle de acesso dos arquivos e aplicação de regras de segurança.
Mesmo diante dessa limitação, não se impediu que os computadores
multiusuário – como o CDC 6600, primeiro supercomputador
do mundo, desenvolvido pela Control Data Corporation, em 1965
– fizessem uso dessa abordagem (Figura 3). Essa técnica ainda é
utilizada em sistemas embarcados mais simples, como em: telefones,
câmeras digitais, MP3 players etc.
Figura 2
Esquema de representação de diretório-raiz, contendo cinco arquivos
Diretório-raiz
A B C D E
Fonte: Elaborada pelo autor.
48 Sistemas Operacionais
Figura 3
CDC 6600
Jitze Couperus/Wikimedia Commons
Primeiro supercomputador do mundo, que fazia uso de diretório-raiz.
Com a evolução do conceito multiusuário, somado ao volume crescente
de arquivos gerados por cada usuário, o modelo de diretório-raiz
não atendia às demandas necessárias. Para solucionar esse problema,
foi criado o modelo de árvore de diretórios (Figura 4), em que os usuários
têm a liberdade de criarem tantos diretórios quanto necessário,
para organizarem os seus arquivos.
Figura 4
Sistema hierárquico de diretórios
Diretório-raiz
Diretório
de
usuário
A
B
C
A
B
B
B
C
C
B
C
C
Fonte: Tanenbaum, 2015, p. 167.
Subdiretórios de usuário
C
C
C
C
Arquivo
de
usuário
Interação do sistema operacional com hardware e software 49
O sistema operacional armazena o sistema de arquivos no disco rígido,
que pode ter uma ou mais partições, isto é, divisões no espaço
do disco. Cada uma das partições de um disco rígido possui o seu próprio
sistema de arquivos. Quando o computador é inicializado, ele lê o
setor 0 do disco rígido, chamado Master Boot Record (MBR, traduzido
como Registro Mestre de Inicialização), o qual é responsável por armazenar
a tabela de partição, uma tabela que contém os endereços
iniciais e finais das partições do disco rígido.
Na sua inicialização, o computador faz uso da BIOS (Basic Input/Output
System – Sistema Integrado de Entrada e Saída), que lê e executa o MBR.
Ao ser executado, o MBR procura ler o primeiro bloco da partição ativa,
chamado de bloco de inicialização, em que está armazenado o sistema
operacional. Ao encontrá-lo, o MBR o executa. Além do bloco de inicialização,
o sistema de arquivos possui alguns outros componentes, como
o superbloco, que armazena os principais parâmetros do sistema de
arquivos e é lido pela memória, quando o computador é inicializado.
O sistema operacional pode fazer uso de diferentes estratégias para
armazenar os arquivos em disco, entre elas, podemos citar:
a. Alocação contígua: o sistema operacional armazena os
arquivos um ao lado do outro. Como vantagens desse método
de alocação, temos a simplicidade de implementação – pois
apenas duas informações precisam ser armazenadas pelo
sistema operacional (o endereço do primeiro bloco do arquivo
e o número total de blocos que ele possui) – e a velocidade de
leitura do arquivo, que pode ser feita em apenas uma operação.
Já entre as desvantagens temos a fragmentação – isto é, o espaço
em disco deixado quando os arquivos começam a ser apagados –
e a dificuldade em se aumentar o tamanho de um arquivo.
b. Alocação por lista encadeada: o sistema operacional armazena
os arquivos em uma lista encadeada de blocos de disco, em que
a primeira palavra serve de ponteiro para o próximo bloco e as
demais são utilizadas para armazenar os dados. Essa estratégia
não sofre efeito da fragmentação, porém a sua leitura é muito
lenta, pois todos os blocos precisam ser lidos para acessar
todos os dados de um arquivo. Podemos citar como exemplo de
sistema operacional que fez uso dessa estratégia o Pick System,
desenvolvido pela MicroData Corporation.
50 Sistemas Operacionais
c. Alocação por lista encadeada usando uma tabela na memória:
uma inovação da alocação por lista encadeada, em que os
ponteiros dos blocos são substituídos por uma tabela na memória
principal, conhecida como File Allocation Table (FAT), traduzida
como Tabela de Alocação de Arquivos. Como vantagens desse
método, o bloco fica livre para armazenar os dados, pois não
precisa mais alocar os ponteiros, e o acesso randômico aos dados
fica facilitado pelo uso da memória. A grande desvantagem é a
necessidade dessa informação estar permanentemente fazendo
uso da memória principal, a qual é considerada uma forma de
armazenamento cara para o sistema operacional.
d. I-nodes (Index-node – nó-índice): o sistema operacional vincula
cada um dos arquivos a uma estrutura de dados chamada
I-nodes, a qual armazena os atributos do arquivo, bem como
os endereços dos seus blocos no disco rígido. Essa estratégia
possui como desvantagem a dificuldade em se definir qual é o
tamanho ideal do índice a ser utilizado, já que, se utilizarmos um
valor pequeno, arquivos grandes não poderão ser armazenados,
e se utilizarmos um valor muito grande, podemos nunca
alcançar esse valor, isto é, não ter arquivos tão grandes quanto o
máximo previsto. Essa dificuldade se baseia no fato de o sistema
operacional não conseguir prever o tamanho de um arquivo a ser
gerado/utilizado por um usuário. Essa estratégia é utilizada pelo
sistema operacional UNIX.
Em 1977, a Microsoft criou a sua primeira versão de FAT no sistema
operacional MS-DOS, e permaneceu nessa versão até o lançamento
do Windows 95. As evoluções vieram com a FAT12, a qual
não foi utilizada comercialmente, seguida pela FAT16, que utilizava
16 bits para o endereçamento de dados, podendo trabalhar com até
65.536 clusters 1 (2 16 ), suportando discos ou partições com até 2GB.
Em 1996, a Microsoft lançou a FAT32, que utilizava 32 bits para o
endereçamento de dados, suportando discos ou partições com até
2TB, sendo utilizada no sistema de arquivos do Windows 95 OSR2 e
do Windows 98. A Microsoft também lançou uma família de sistemas
operacionais para servidores corporativos, chamada Windows NT. Em
1993, o Windows NT 3.1 apresentou um novo sistema de arquivos,
chamado NT File System (NTFS), o qual acabou se tornando o padrão
de todos os sistemas operacionais desenvolvidos pela Microsoft, a
1
Um cluster é uma unidade de
alocação de espaço em disco utilizada
por arquivos e diretórios.
Interação do sistema operacional com hardware e software 51
Livro
Para compreender um
pouco mais sobre o
motivo da existência dos
arquivos e dos diretórios
e como o sistema operacional
interage com
eles, leia o livro Sistemas
operacionais: projeto e
implementação.
TANENBAUM, A. S.; WOODHULL, A. S.
3. ed. São Paulo: Bookman, 2008.
partir do Windows 2000. O NTFS apresentou várias melhorias ao ser
comparado com a FAT, entre elas: o aumento para o volume total
suportado por discos e partições para 256TB; a utilização de clusters
de 512 bytes; um melhor desempenho; a possibilidade de aplicar políticas
de segurança; e a recuperação de falhas por meio do journal,
isto é, um arquivo de log, que grava os eventos em uma área específica
do disco rígido, para depois fazer a gravação efetiva.
A maioria das distribuições Linux faz uso do sistema de arquivos
Fourth Extended Filesystem (ext4) – traduzido como Quarto Sistema
de Arquivos Estendido –, suportando discos e partições com até 1
exabyte (EB) – que equivale a 1.000.000.000.000.000.000 bytes – e
arquivos com tamanho de até 16TB.
A implementação em diretórios segue a estratégia utilizada para
armazenar os arquivos, pois antes de abrir e executar um arquivo, o
sistema operacional precisa localizar qual caminho ele utiliza.
2.2 Interpretadores e compiladores
Vídeo
Cada computador possui a sua própria linguagem, chamada linguagem
de máquina, que é composta de sequências de zero e um.
Essa linguagem permite ao computador a realização de suas tarefas,
sendo definida pelo seu projeto de arquitetura. Utilizada pelos
programadores nos primeiros computadores, essa abordagem se
revelou lenta e passível de erros de acordo com a utilização dos computadores.
Como alternativa, os programadores começaram a fazer
uso de abreviaturas da língua inglesa (load, add, store etc.) para representar
as operações básicas do computador. Isso originou as linguagens
de montagem, que faziam usos de programas montadores
(assemblers) para converter o código-fonte escrito em linguagem de
montagem para a linguagem de máquina, a qual seria reconhecida
pelo computador. Embora seja muito mais simples de se compreender
e rápida para se programar do que a linguagem de máquina, a
linguagem de montagem fazia uso de muitas instruções para a realização
de uma única tarefa. Em virtude dessa deficiência, foram desenvolvidas
as linguagens de alto nível, que executam tarefas com
menos instruções. Elas fazem uso de programas, chamados compiladores,
para converter o código-fonte para linguagem de máquina.
Como exemplos de linguagens de alto nível, podemos citar:
52 Sistemas Operacionais
a. FORTRAN – desenvolvida pela IBM na década de 1950 (Figura 5),
com propósito científico e de engenharia, é considerada a primeira
linguagem de programação multiplataforma, isto é, utilizada em
diferentes arquiteturas. Sendo ainda utilizada em mainframes 2
na atualidade.
Figura 5
Código FORTRAN em um cartão perfurado
Arnold Reinhold/Wikimedia Commons
2
Mainframes são computadores
usados principalmente por
grandes organizações para aplicações
críticas e processamento
de dados massivos, como:
estatísticas da indústria e do
consumidor, planejamento de
recursos empresariais e processamento
de transações. Eles são
maiores e têm mais poder de
processamento do que algumas
outras classes de computadores,
como: minicomputadores,
servidores, estações de trabalho
e computadores pessoais.
b. Common Business Oriented Language (COBOL) – traduzida como
Linguagem Comum Orientada para Negócios, foi desenvolvida
pelo Conference on Data Systems Languages (CODASYL), em
1959, com propósito comercial, e ainda é a mais utilizada em
mainframes na atualidade.
c. C – desenvolvida por Dennis Ritchie, pesquisador da Bell
Laboratories, no início da década de 1970. A linguagem C ganhou
destaque ao ser utilizada no desenvolvimento do sistema
operacional UNIX.
d. C++ – desenvolvida por Bjarne Stroustrup, também pesquisador
da Bell Laboratories, no início da década de 1980. A linguagem
C++ é uma extensão da linguagem C voltada para a Programação
Orientada a Objeto (POO). Segundo Deitel, Deitel e Choffnes
(2005), objetos são componentes de software reutilizáveis que
modelam itens do mundo real.
e. Java – desenvolvida por James Gosling, pesquisador da Sun
MicroSystems, em 1995, com propósito de ser utilizada em
aplicações baixadas pela web e/ou executadas nos navegadores
(browsers). Java é uma linguagem orientada a objeto. O sistema
operacional Android, desenvolvido pela Google, utilizou a
linguagem Java no seu desenvolvimento.
Interação do sistema operacional com hardware e software 53
f. C# – desenvolvida pela Microsoft, em 2000, com o propósito de
ser a linguagem principal da plataforma de desenvolvimento,
chamada .NET. A C# é uma linguagem orientada a objeto, que
une conceitos de outras linguagens, como: C, C++ e Java.
Enquanto os compiladores convertem código-fonte escrito em
uma linguagem de alto nível para a linguagem de máquina, os interpretadores
executam o código-fonte, ou uma versão convertida
para a linguagem de baixo nível, isto é, para a linguagem mais
próxima da linguagem de máquina. Cabe ao interpretador converter
as solicitações recebidas para linguagem de máquina. Apesar
dessa vantagem, a necessidade de leitura, interpretação e execução
por parte dos interpretadores torna a sua execução mais lenta
do que a dos programas compilados, que já estão em linguagem
de máquina.
2.3 Firmware e middleware
Vídeo Segundo Deitel, Deitel e Choffnes (2005), firmwares são instruções
executáveis armazenadas em memória não volátil (que não se perde
quando o computador é desligado), voltadas, em grande parte, para
operações de leitura. O firmware é desenvolvido por meio de microprogramação,
ou seja, uma camada desenvolvida em microcódigo, que
inclui instruções em linguagem de máquina, as quais são utilizadas
pelo hardware. Atualmente, o microcódigo é escrito na linguagem C e
compilado em linguagem de máquina, para ser reconhecido pelo chip
que vai armazená-lo.
A utilização do firmware permite que os fabricantes de dispositivos
utilizem chips programáveis, de uso geral, em vez de utilizarem
hardware de uso personalizado. Isso resulta em economia de custos,
além da facilidade de inovação e implantação, pois se torna mais fácil
adicionar uma funcionalidade por meio de uma alteração do firmware,
do que com a substituição do chip.
O conceito de microprogramação foi criado em 1951, por Maurice
Wilkes, professor emérito da Universidade de Cambridge, que participou
da construção do computador Electronic Delay Storage Automatic
Calculator (EDSAC) – traduzido como Calculadora Automática de Armazenamento
de Atraso Eletrônico (Figura 6).
54 Sistemas Operacionais
Figura 6
Computador EDSAC em junho de 1948
Thorpe/Wikimedia Commons
Porém, somente em 1964, com o lançamento do System/360,
utilizado pela IBM nos computadores da série 360, é que a microprogramação
passou a ser utilizada amplamente, atingido o seu
ápice no sistema operacional VAX, desenvolvido pela Digital Equipment
Corporation (DEC), na metade dos anos 1970. Atualmente, a
microprogramação é utilizada em vários aparelhos, como: controle
remoto da TV, discos rígidos, players de blu-ray, câmeras digitais,
teclados, webcams, fornos micro-ondas etc.
Segundo Deitel, Deitel e Choffnes (2005), o middleware permite
que uma aplicação seja executada em um computador e se comunique
com uma outra, executada em um outro computador, quando
ambos fazem parte de um sistema distribuído. Isso é importante,
pois os sistemas distribuídos, geralmente, são compostos de computadores
que fazem uso de sistemas operacionais, hardware, arquitetura
e protocolos de rede diferentes. O middleware também
permite a execução de aplicações em ambientes de computação
heterogêneos, desde que estes façam uso de um middleware comum
entre eles.
O middleware vem retirar um peso dos ombros dos desenvolvedores,
pois não seria mais necessário que eles adicionassem
Interação do sistema operacional com hardware e software 55
protocolos de comunicação aos seus aplicativos, ficando essa
responsabilidade por conta do middleware. Isso se dá porque o
middleware faz uso de uma Application Programming Interface (API)
– Interface de Programação de Aplicações –, isto é, um conjunto
de rotinas e padrões definidos por um software, o qual permite
que um aplicativo utilize os seus serviços sem a necessidade de
se aprofundar na forma com que ele foi desenvolvido (Figura 7).
Podemos citar como exemplos de APIs: Portable Operating System
Interface (POSIX), utilizada nos sistemas baseados no UNIX; e a API
do Windows, utilizada como padrão para o desenvolvimento de
aplicações que serão executadas no sistema operacional Windows,
da Microsoft.
Figura 7
Interface de Programação da Aplicação (API)
Aplicação
API
Espaço do usuário
Espaço do núcleo
Interface de chamada ao sistema
Memória Disco Rede
Fonte: DeiteL; Deitel; Choffnes, 2005, p. 51.
Podemos citar como exemplos de middleware: a Open Database
Connectivity (ODBC) – Conectividade Aberta para Bancos de Dados
–, desenvolvida pela Microsoft e Simba Technologies, a qual é uma
API que permite às aplicações acessar o conteúdo dos bancos de
dados; a Common Object Request Broker Architecture (CORBA) – Arquitetura
de Broker de Solicitação do Objeto Comum –, um middleware
desenvolvido pelo Object Management Group (OMG), que consiste
em um conjunto de protocolos e implementações que possibilitam
e simplificam a troca de informações entre os sistemas distribuídos
heterogêneos; e a Open Graphics Library (OpenGL) – Biblioteca
de Gráficos Aberta –, um middleware desenvolvido pela Silicon
Graphics, Inc. (SGI) para a renderização de vetores gráficos 2D e
56 Sistemas Operacionais
3D. Sua API é utilizada na interação com a Graphics Processing
Unit (GPU) – Unidade Gráfica de Processamento – para
obter uma renderização acelerada por meio do hardware.
Os sistemas operacionais e o middleware têm muito em
comum: são softwares utilizados para oferecer suporte a
outros softwares, como os aplicativos, que o usuário executa;
além disso, fornecem um leque semelhante de serviços,
centrado na interação controlada. Como um sistema operacional,
o middleware pode impor algumas regras, projetadas
para impedir que as suas operações interfiram entre si
(Figura 8).
O middleware fornece os serviços por meio de sua API, fazendo
uso dos recursos suportados pelo sistema operacional
que o hospeda. Por exemplo, o usuário solicita ao middleware
a atualização de tabelas de um banco de dados, para executar
essa tarefa, o middleware faz uso da capacidade do sistema
operacional de ler e gravar os arquivos desse banco de dados.
Figura 8
Posição do middleware em
relação às aplicações e ao
sistema operacional
Aplicação
Middleware
Sistema Operacional
Fonte: Elaborada pelo autor.
2.4 Processadores
Vídeo Por processador compreendemos um componente de hardware
que executa linguagem de máquina (assembly) e que pode ser encontrado
em vários formatos dentro da máquina. Podendo se apresentar
como uma Central Processing Unit (CPU) – Unidade Central de Processamento
–, que executará as instruções de um programa; ou um processador
gráfico ou de sinais digitais (Digital Signal Processor – DSP), que
executará instruções específicas.
O sistema operacional fornece mecanismos de proteção ao processador,
evitando que os processos tenham acesso a instruções
privilegiadas ou em memória. Os sistemas operacionais, em geral,
dispõem de diferentes modos de execução: o modo usuário (estado
usuário ou estado-problema), em que o usuário poderá executar
apenas um subconjunto de instruções, impedindo-o de acessar as
informações de outro usuário ou mesmo de causar dano ao sistema
operacional; e o modo núcleo (estado supervisor), no qual o processador
pode acessar instruções privilegiadas e recursos, em nome
dos processos.
Interação do sistema operacional com hardware e software 57
2.4.1. Desempenho de processador
Os primeiros computadores não faziam uso de sistemas operacionais,
pois tais sistemas foram criados posteriormente. Portanto, o
hardware ocupava lugar de destaque e era a prioridade nas pesquisas
realizadas, fazendo com que seu custo fosse elevado. Com o passar do
tempo, o software foi ocupando um espaço maior e aumentando a sua
complexidade, fazendo com que o preço do hardware se tornasse mais
acessível. Como o usuário interage com o software e este é responsável
pela interação com o hardware, pois acaba ocultando as atividades que
são realizadas pela máquina, dificultando a real percepção de desempenho
do ponto de vista mecânico, cria a necessidade de softwares
indicadores de desempenho para registrar e exibir valores mais confiáveis
para o usuário.
O desempenho do sistema operacional está fortemente vinculado
ao desempenho do processador. Segundo Deitel, Deitel e Choffnes
(2005), conceitualmente, um processador pode ser dividido em um
conjunto de instruções, o qual é o conjunto de instruções de máquina
que ele pode executar, e sua implementação, que é o hardware.
Os projetistas de processadores fazem uso de um padrão conhecido
como Instruction Set Architecture (ISA) – Arquitetura do Conjunto de
Instruções –, no qual é feita a descrição do processador, seu conjunto
de instruções, o seu número de registradores e o seu tamanho de memória.
As abordagens da ISA evoluíram com o passar dos anos, como
veremos a seguir.
2.4.1.1. Processadores CISC
Os processadores Complex Instruction Set Computing (CISC) –
Computação com Conjunto de Instruções Complexas – surgiram
na metade dos anos 1960. Eles possuíam um conjunto de instruções
que podiam executar diversas operações, em virtude disso,
os programadores de linguagem de montagem podiam escrever o
código-fonte dos seus softwares com um menor número de linhas,
já que muitas das instruções, que antes faziam parte do software,
estavam incorporadas no processador. Podemos citar, como exemplos
de processadores CISC, as famílias de processadores 386 e
58 Sistemas Operacionais
486, desenvolvidas pela Intel. Quando surgiram os processadores
CISC, boa parte dos sistemas operacionais era escrito em linguagem
de montagem, porém eles perderam força quando os sistemas
operacionais passaram a ser escritos em linguagens de alto
nível, por exemplo, o uso do C e do C++ no código-fonte do sistema
operacional UNIX.
A adoção dos processadores CISC foi motivada pela queda no
custo do hardware somada ao aumento do custo para desenvolvimento
do software. Segundo Deitel, Deitel e Choffnes (2005), os
processadores CISC tentavam transferir muito da complexidade do
software para o hardware, reduzindo o tamanho dos programas,
diminuindo o acesso à memória e facilitando o processo de depuração
do código-fonte. Um outro benefício da arquitetura de processadores
CISC foi a diminuição no número de registradores de
propósito geral, reduzindo o custo do processador e permitindo a
inclusão de outras estruturas CISC no projeto. Uma inovação lançada
pela arquitetura de processadores CISC foi o uso do pipeline,
que dividia o caminho dos dados dentro do processador, permitindo
que este executasse várias instruções simultaneamente.
2.4.1.2. Processadores RISC
Os avanços do hardware e o uso de compiladores, por meio de
estudos realizados por várias empresas, inclusive a IBM, demonstraram
que o conjunto de instruções armazenados pelos processadores
CISC não estavam sendo utilizados, ou se tornaram mais
lentos, ocupando grande parte do tempo de processamento. Essa
descoberta fortaleceu o desenvolvimento dos processadores Reduced
Instruction Set Computing (RISC) – Computação com Conjunto de
Instruções Reduzidas –, nos quais as atividades mais comuns do
processador deveriam ser executadas de maneira mais eficiente.
Os processadores RISC seguiram caminho inverso dos processadores
CISC. Neles, a complexidade da programação foi transferida
do hardware para o código-fonte compilado. As unidades de
controle dos processadores RISC são desenvolvidas em hardware,
reduzindo o tempo de execução quando comparados com os conjuntos
de instruções dos processadores CISC. Outra vantagem é
Interação do sistema operacional com hardware e software 59
3
Pipelines de instruções são
usados nas CPUs para permitir
a sobreposição de execução de
várias instruções com o mesmo
circuito.
4
Figura 9
Raspberry PI 4
modelo B
Raspberry Pi é uma série de
pequenos computadores desenvolvida
no Reino Unido pela
Raspberry Pi Foundation, para
promover o ensino de ciência da
computação básica nas escolas e
países em desenvolvimento.
que as instruções dos processadores RISC fazem uso de palavras
com tamanho fixo de memória, diferentemente das instruções dos
processadores CISC, as quais faziam uso de palavras com tamanhos
variados, o que gerava um tempo maior de execução. Como
os processadores RISC não necessitavam de estruturas CISC no seu
projeto, eles aumentaram o número de registradores de propósito
geral, diminuindo a necessidade de acesso à memória.
Como as instruções utilizadas pelos processadores RISC são
mais simples e possuem o mesmo tamanho, torna-se possível o
uso dos pipelines 3
de modo mais eficiente que os processadores
CISC. Uma inovação lançada pela arquitetura de processadores
RISC foi o uso da técnica conhecida como desvio atrasado, a qual
permite que, ao receber um conjunto de instruções sequenciais,
a sua totalidade possa ou não ser executada de acordo com
uma validação feita pelo processador. Como desvantagens
da arquitetura de processadores
RISC, em comparação com a arquitetura de
processadores CISC, podemos destacar: as
operações que fazem uso de pontos flutuantes
são mais rápidas nos processadores
CISC; e a utilização de programas gráficos e científicos
apresenta melhor desempenho quando executada
em processadores CISC, pois esses programas fazem uso
de instruções complexas de maneira repetida.
Podemos citar como exemplo de utilização da arquitetura RISC,
o processador PowerPC, desenvolvido pela IBM e que foi utilizado
pela Apple em seus computadores. A arquitetura RISC deu origem a
vários novos projetos de processadores, entre eles, podemos destacar
o Advanced RISC Machine (ARM) – Máquina RISC Avançada – ,
desenvolvido pela Acorn Computers. Esse projeto é utilizado, amplamente,
em smartphones, tablets e no Raspberry PI 4 (Figura 9).
2.4.2. Projeto de processador
Segundo Deitel, Deitel e Choffnes (2005), mesmo diante da variedade
de tipos de processadores, alguns componentes são comuns, conforme
representado na figura a seguir.
60 Sistemas Operacionais
Figura 10
Componentes do processador
ULA
Unidade de
execução
Unidade de
busca/decodificação
Registradores
Cache de
instrução L1
Cache de
dados L1
Cache L2
Interface de barramento
Fonte: Deitel; Deitel; Choffnes, 2005, p. 34.
a. A Unidade de Controle (UC) é responsável pela busca das
instruções na memória principal (MP), pela sua decodificação e
execução. Para realizar essas atividades, ela faz uso da Unidade
de Busca de Instrução, responsável por carregar as instruções
em memórias de alta velocidade, isto é, os registradores de
instruções, os quais permitem ao processador executá-las
rapidamente; e da Unidade de Decodificação de Instrução,
que realiza a interpretação da instrução e a encaminha para
a Unidade de Execução. O uso de sinais elétricos (pulsos
de controle) permite à UC controlar os componentes de
dispositivos do computador. Dentre as atividades pelas quais
a UC é responsável, podemos citar: o início e término da
leitura de dados, o controle do armazenamento das palavras
na memória, a execução de uma instrução, o início de uma
operação aritmética etc.
b. Os registradores são responsáveis por armazenar os dados
para uso imediato pelo processador. A velocidade e a
proximidade dos registradores com a UC permitem que o
processador não fique ocioso. O tamanho dos registradores
Interação do sistema operacional com hardware e software 61
é determinado pelo número de bits definido pela arquitetura
do processador, isto é, um processador de 64 bits pode
armazenar 64 bits de dados em cada registrador. A arquitetura
do processador também define o seu número de registradores,
por exemplo, o Pentium 4 da Intel possuía 16 registradores
de execução de programa; já o PowerPC 970 da IBM, utilizado
nos computadores G5 da Apple, possuía 32 registradores. Os
registradores se dividem em dois grupos: os registradores de
propósito geral, que são utilizados para guardar as variáveis
dos programas e permitem à CPU acessá-las sem ter de buscálas
na memória principal; e os registradores de propósito
específico, dentre os quais podemos citar o Contador de
Programas (Program Counter – PC), que contém o endereço de
memória a ser utilizado na busca da próxima instrução a ser
executada pela CPU; o Registrador de Instrução (Instruction
Register – IR), o qual recebeu a instrução que veio da memória
e tem o objetivo de guardar a instrução e passá-la para a UC;
o Registrador de Endereço (Memory Address Register – MAR) e o
Registrador de Dados (Memory Buffer Register – MBR), os quais
possuem funções análogas ao PC e ao IR, mas referentes a
dados e não a instruções (Figuras 11 e 12).
Figura 11
Estrutura de uma CPU
Instruções
Unidade de
Controle
Controles
externos
Endereço das
Instruções
Controles internos
Condições
Dados
Unidade de
Execução
Dados
CPU
Endereço dos
dados
Fonte: Elaborada pelo autor.
62 Sistemas Operacionais
Figura 12
Estrutura de uma CPU com registradores
Instruções
Endereço das
Instruções
IR
PC
Controles internos
Unidade de
Controle
Condições
Controles
externos
Dados
MBR
MAR
Dados
CPU
Registradores de propósito geral
ULA
Endereço dos
dados
Fonte: Elaborada pelo autor.
Unidade de
Execução
c. A parte principal da Unidade de Execução é a Unidade de
Lógica e Aritmética (ULA), que se assemelha muito a uma
calculadora convencional, executando operações lógicas e
aritméticas, com números inteiros ou reais. Os registradores
de propósito geral ou específicos são responsáveis por trazer
tipos de dados diferentes para a ULA. Cabe à UC decidir quais
os registradores encaminharão seus dados para a ULA e
informar qual operação (soma, multiplicação, divisão, AND, OR
etc.) será realizada. Após a execução da operação, a ULA gera
um resultado, o qual é entregue para um registrador também
definido pela UC. A ULA é, normalmente, representada por
um V nos diagramas de arquitetura.
d. A interface de barramento (Figura 13) é responsável
pela interação do processador com a memória e os outros
dispositivos do sistema. Essa interface executa três funções
distintas: o barramento de dados, cuja função é realizar o
transporte dos dados ou instruções, realizando essa operação
em sentido bidirecional; o barramento de endereços, cuja
Interação do sistema operacional com hardware e software 63
função é indicar o endereço de memória que o processador
deve ler ou gravar, realizando essa operação em sentido
unidirecional; e o barramento de controle, cuja função é
monitorar as ações dos outros dois barramentos, gerenciando
as solicitações e confirmações, realizando essa operação em
sentido bidirecional.
Figura 13
Estrutura de uma CPU com barramentos
Memória principal
Instruções
Controles
extremos
Barramento de dados
Barramento de endereços
Endereço das
instruções
Dados
CPU
Unidade de
controle
Controles internos
Unidade de
execução
Condições
Dados
Endereço
dos dados
Barramento de dados
Barramento de endereços
Barramento de controle
Fonte: Elaborada pelo autor.
e. Por meio da interface de barramento, os dados da memória
principal são copiados para a memória cache do processador,
a qual atinge velocidades muito mais altas que a memória
principal. Essa cópia aumenta a eficiência do processador por
meio do acesso rápido aos dados e às instruções. A memória
cache é classificada em dois níveis: o cache Nível 1 – Level
1 (L1) –, que é o nível mais rápido e mais caro, localizado
dentro do processador; e o cache Nível 2 – Level 2 (L2) –, que
é maior e mais lento que o L1. Normalmente localizado na
placa principal (motherboard – mainboard – placa-mãe), ele
vem sendo deslocado para o processador, para melhorar o
seu desempenho.
64 Sistemas Operacionais
2.4.3. Gerenciamento de multiprocessador
Segundo Deitel, Deitel e Choffnes (2005), o termo sistema de multiprocessamento
engloba qualquer sistema que contenha mais de um
processador. Podemos citar como exemplos de sistemas multiprocessados
os notebooks, os quais possuem dois processadores, e os servidores
de aplicação ou bancos de dados, hospedados em datacenters, 5
que possuem vários processadores.
As diferentes possibilidades de arquiteturas para se construir um projeto
de multiprocessadores destacam mais uma característica desse tipo
de projeto, a forma com que eles compartilham recursos dentro do sistema
computacional. Analisando essa característica, temos duas opções:
5
Datacenter é um ambiente
projetado para concentrar os servidores,
os equipamentos para
processamento e armazenamento
dos dados e os equipamentos
de redes de computadores.
a. Os sistemas fortemente acoplados
– Tightly Coupled Systems –, em que
os processadores compartilham a
maior parte dos componentes do
sistema. Esse modelo faz uso de um
sistema operacional centralizado. O
projeto Pentium, que conta com dois
processadores, e foi desenvolvido
pela Intel, faz uso desse modelo.
b. Os sistemas fracamente acoplados
– Loosely Coupled Systems –, em que
a comunicação entre o processador
e os componentes é feita por enlaces
de comunicação. As vantagens do uso
desse modelo estão na sua flexibilidade
e escalabilidade, pois os componentes
podem ser incluídos ou retirados do
projeto com maior facilidade do que
comparado ao modelo fortemente
acoplado. O fato de utilizar um enlace
de comunicação torna esse modelo
menos eficiente. O projeto Earth
Simulator, desenvolvido pelo governo
do Japão, faz uso desse modelo.
Artigo
https://www.researchgate.net/profile/Cesar_Zeferino/publication/266878017_Processadores_para_
Ensino_de_Conceitos_Basicos_de_Arquitetura_de_Computadores/links/5575ee1308ae75363751a4b2/
Processadores-para-Ensino-de-Conceitos-Basicos-de-Arquitetura-de-Computadores.pdf
O artigo Processadores para Ensino de Conceitos Básicos de Arquitetura de Computadores,
dos autores Diana Morandi, André Luis Alice Raabe e Cesar Albenes
Zeferino, apresentado no Workshop sobre Educação em Arquitetura de Computadores,
em 2006, pode aprofundar os seus conhecimentos sobre arquitetura
de processadores, seus componentes e a função de cada um deles.
Acesso em: 3 ago. 2020.
Interação do sistema operacional com hardware e software 65
2.5 Memória
Vídeo
Quando analisamos hardware, ao discutir um projeto de sistema
operacional, devemos levar em consideração algumas verdades
absolutas, a primeira delas é que o hardware maior é mais lento que o
hardware menor (Figura 14), isso ocorre por causa dos atrasos de propagação
de sinal. Tomando a memória como exemplo, quanto maior a
memória, maior será o seu atraso de sinal e maior o número de níveis
para decodificação dos endereços.
Figura 14
Tempo de acesso X Tamanho da memória
Nível 1
Nível 2
...
Aumento
do tempo
de acesso
Nível n
Tamanho da memória
A segunda verdade absoluta é que, na maioria das tecnologias, podemos
obter memórias menores, as quais são mais rápidas do que
memórias maiores. As memórias mais rápidas estão, geralmente, disponíveis
em números menores de bits (dígito binário ou binary digit,
que corresponde à unidade básica utilizada pelo computador no seu
processamento; o bit pode assumir apenas dois valores: zero e um
ou true e false) por CI (Circuito Integrado) e custam, substancialmente,
mais por byte, o qual corresponde a uma sequência de oito bits.
Ao observar a execução de um software, descobriu-se que, dentro
de um intervalo de tempo, os endereços gerados por essa execução
tendem a se limitar a pequenos conjuntos, sendo chamado esse fenômeno
de princípio da localidade, que se baseia na observação de três
tipos diferentes de localidade destacadas a seguir.
••
A localidade temporal – observa uma tendência por parte de
um processo em realizar referências futuras a posições feitas
recentemente.
66 Sistemas Operacionais
••
A localidade espacial – observa uma tendência por parte de um
processo em realizar referências a posições na vizinhança da última
referência.
••
A localidade sequencial – observa uma tendência por parte de
um processo em fazer referência à posição seguinte a atual.
Levando isso em consideração, os projetistas de hardware optaram
por manter os itens que foram utilizados mais recentemente na memória
mais rápida e próxima possível da CPU.
2.5.1 Hierarquia de memória
Segundo Deitel, Deitel e Choffnes (2005), a hierarquia de memória
é um esquema de categorização da memória, em que a mais rápida
e mais cara fica no topo da hierarquia, enquanto a mais lenta e mais
barata fica na base. Os níveis da hierarquia são subconjuntos uns dos
outros, isto é, todos os dados encontrados em um nível também são
encontrados no nível abaixo dele e isso se repete até o fim da hierarquia
(Figura 15).
Figura 15
Hierarquia de Memória
Tempo típico de
acesso
1 ns
2 ns
10 ns
10 ms
100 s
Registradores
Caches
Memória principal
Disco magnético
Fita magnética
Capacidade
típica
<1 KB
4 MB
512-2.048 MB
200-1.000 GB
400-800 GB
Fonte: Tanenbaum; Bos, 2015, p. 14.
O topo da hierarquia é ocupado pelos registradores internos à
CPU, os quais são feitos do mesmo material que ela, garantindo
velocidade no acesso aos dados e às instruções. Abaixo dos registradores
internos, encontramos a memória cache, geralmente
controlada por hardware.
Em seguida, na hierarquia, vem a memória principal – também chamada
memória real ou memória física. Segundo Deitel, Deitel e Choffnes
(2005), a memória principal de um sistema computacional corresponde
ao nível mais baixo de armazenamento de dados, dentro da hierarquia
de memória, que o processador pode acessar diretamente.
Interação do sistema operacional com hardware e software 67
Os registradores internos, a memória cache e a memória principal
são considerados meios de armazenamento voláteis, isto é,
quando o fornecimento de energia do computador é interrompido,
os dados armazenados são perdidos.
Por último, na hierarquia de memória, encontramos a memória
secundária, composta de dispositivos de armazenamento secundário
e terciário, por exemplo: disco rígido (HD – Hard Disk), fita
magnética, CD, DVD etc. Por ocuparem o último lugar na hierarquia,
os dispositivos de memória secundária são os menos caros e
os mais lentos entre todos eles. A memória principal e a secundária
são as memórias a que o usuário tem acesso.
O sistema operacional faz uso de um mecanismo chamado
memória virtual (segmentação e/ou paginação) para iludir o usuário,
fazendo-o acreditar que a memória total do seu computador é
a soma da memória principal e da memória secundária. Esse mecanismo
permite a transferência dos blocos de informação entre
essas duas memórias, automaticamente, sem a intervenção e o conhecimento
do usuário.
O armazenamento terciário vem como uma solução para sistemas
que necessitam de níveis de memória superiores ao que
o armazenamento secundário oferece. Essa extensão é feita por
meio do armazenamento de dados em fitas magnéticas, catalogadas
e acessadas por braços robóticos, as quais armazenam dados
importantes, porém com uma frequência de acesso inferior
aos que estão sendo armazenados no disco rígido. Podemos citar,
como exemplo, uma instituição financeira que precisa armazenar
contratos por trinta anos; conforme o tempo passa, os contratos
mais antigos deixam de ser consultados com frequência, podendo
ser migrados dos discos rígidos (armazenamento secundário) para
as fitas magnéticas (armazenamento terciário). Isso libera espaço
em disco para dados mais novos, que serão armazenados com uma
constância maior.
2.5.2 Memória principal
Segundo Tanenbaum e Bos (2015), a memória principal, muitas
vezes chamada de RAM (Random Access Memory – Memória de Acesso
Aleatório), é a locomotiva do sistema de memória. Entre os anos
68 Sistemas Operacionais
1950 e 1960, ela era conhecida como memória de núcleos (core memory),
pois era fabricada com pequenos núcleos de ferrita, isto é,
um material cerâmico, composto principalmente de óxido de ferro,
com propriedades magnéticas. Nos computadores atuais, a memória
principal possui centenas de megabytes (MB), sendo que cada
MB equivale a um milhão de bytes. Quando as requisições feitas
pela CPU não podem ser atendidas pela memória cache, elas são
encaminhadas para a memória principal.
A memória RAM é caracterizada como uma memória de acesso
aleatório, pois os processos podem acessar as localizações de
dados em qualquer sequência, diferentemente do que ocorria no
armazenamento feito em fita magnética, no qual o dado somente
era acessado quando a leitora chegava no ponto específico em que
ele foi gravado na fita.
Como já mencionado, memória principal é uma memória
volátil, isto é, ela perde o conteúdo quando o fornecimento de
energia do sistema é interrompido. Um outro exemplo de memória
volátil, utilizada pelos computadores, é a memória Complement-ary
metal–oxide–semiconductor (CMOS) – Metal-óxido-semicondutor de
simetria complementar –, utilizada para manter a data e a hora do
computador atualizadas. A memória CMOS é alimentada por uma
pequena bateria, a qual garante o funcionamento regular do relógio
do computador, mesmo que ele esteja desligado.
Porém, alguns computadores fazem uso de memória aleatória
não volátil. Podemos citar, como exemplo, a memória ROM (Read
Only Memory – Memória Somente de Leitura), que já vem programada
de fábrica e não pode ser utilizada pelo usuário. O processo
de inicialização do computador, feito pelo carregador (bootstrap
loader) é gravado nessa memória ROM, que é uma memória rápida
e de baixo custo.
2.5.3 Armazenamento secundário
Em virtude da limitação de capacidade e volatilidade, a memória
principal não é adequada para o armazenamento permanente
de grande quantidade de dados, como os softwares e arquivos de
dados gerados pelo usuário. Para resolver esse problema, o computador
faz uso do armazenamento secundário (armazenamento
Interação do sistema operacional com hardware e software 69
persistente ou auxiliar), no qual ele armazena grande quantidade
de dados permanentes a um baixo custo, sendo estes mantidos
mesmo que o computador seja desligado. Porém, acessar os dados
armazenados em um disco rígido é mais lento do que acessá-los
na memória principal. Para facilitar a realização de cópias de segurança
dos dados (backup) e a transferência de dados entre
computadores, os usuários passaram a utilizar dispositivos de armazenamento
secundário removíveis, como: CDs, DVDs, pendrives
etc. Apesar da praticidade, esses dispositivos são mais lentos que
o disco rígido.
2.6 Discos e fitas
6
Vídeo
Uma ordem de magnitude
ou ordem de grandeza é uma
classe de escala ou magnitude
de qualquer quantidade ou
grandeza, em que cada classe
contém valores de uma razão
à classe que a precede. A razão
mais comumente usada é dez.
A forma mais comum de armazenamento secundário nos computadores
é o disco rígido, sendo classificado como um dispositivo de
bloco, pois transmite os dados em tamanhos fixos de bytes. Entre
centenas de bytes, há dezenas de KB (kilobytes), isto é, aproximadamente
1.000 bytes.
Segundo Tanenbaum e Bos (2015), o armazenamento no disco
rígido é duas ordens de magnitude 6
mais barato, por bit, do que o
da memória RAM. Porém, o tempo de acesso aos dados é cerca de
três ordens de magnitude mais lento. O motivo dessa lentidão reside
no fato de o disco rígido ser um dispositivo mecânico, conforme
mostra a figura a seguir.
Figura 16
Estrutura de uma unidade de disco
Superfície 7
Cabeça de
leitura/escrita
(uma por superfície)
Superfície 6
Superfície 5
Superfície 4
Superfície 3
Superfície 2
Superfície 1
Direção do
movimento
do braço
Superfície 0
Fonte: Tanenbaum e Bos, 2015, p. 15.
70 Sistemas Operacionais
Em seu interior, um disco rígido é constituído por um ou mais
pratos metálicos, que giram com velocidade entre 5.400 e 10.800
rpm (rotações por minuto). Os dados são lidos e escritos nesses pratos
metálicos por um braço mecânico. Uma região circular, lida pelo
braço, em um dos pratos metálicos é chamada de trilha. A soma de
todas as trilhas, em um movimento de leitura feito pelo braço, do
começo ao fim do prato metálico, é chamada de cilindro. Compreendemos
como latência rotacional a lentidão no uso do disco rígido,
pela necessidade de mover o braço mecânico entre os pratos até
que os dados sejam acessados, somada ao tempo de transferência
para a memória principal, depois da leitura. Para que um programa
possa ser executado, ele é armazenado no disco rígido, transferido
para a memória principal, na qual poderá ser acessado pelo processador,
e, por fim, executado.
Segundo Tanenbaum e Bos (2015), a fita magnética ocupa a última
camada da hierarquia de memória, sendo utilizada como cópia
de segurança (backup) dos dados armazenados em disco ou para armazenar
grandes quantidades de dados. O acesso aos dados é feito
por meio de uma unidade leitora de fitas, a qual é inserida manualmente
ou por braços robóticos, utilizados nos grandes centros, como
instituições financeiras. Como vantagens do uso da fita magnética,
podemos destacar o baixo custo por bit e o fato de ser uma forma
de armazenamento removível, o que permite, no caso de um backup,
o armazenamento físico longe do local de processamento, protegendo
os dados contra roubos, incêndios, catástrofes naturais etc. Como
desvantagem do uso da fita magnética, podemos destacar o acesso
sequencial, no qual a fita terá de ser percorrida até que o dado solicitado
seja encontrado. Esse tipo de operação pode demorar alguns
minutos para ser realizada.
2.7 Dispositivos de E/S e barramentos
Vídeo Nesta seção, apresentaremos os barramentos, que atuam como
meios de comunicação entre as diversas partes de hardware envolvidas
no funcionamento do computador, e os dispositivos de E/S, os
quais são os periféricos acoplados ao computador que realizam a interação
com o usuário.
Interação do sistema operacional com hardware e software 71
2.7.1 Barramentos
Segundo Deitel, Deitel e Choffnes (2005), um barramento é um
conjunto de pistas, ou de outras conexões elétricas, que transportam
informações entre dispositivos de hardware. Como tipos de barramentos,
podemos citar:
a. os barramentos de dados – são responsáveis pelo transporte
de dados;
b. os barramentos de endereços – armazenam e informam o
endereço, em que os dados estão armazenados;
c. as portas – permitem a conexão entre dois dispositivos;
d. os canais de E/S – permitem a realização de operações de
E/S por meio de um barramento compartilhado entre vários
dispositivos. Os canais de E/S podem tentar acessar a memória
ao mesmo tempo que o processador. Para evitar a colisão no
barramento, um dispositivo de hardware, chamado controlador,
fica responsável por esse processo. Porém, os canais de E/S
acabam, em um determinado momento, consumindo ciclos de
acesso à memória do processador, mesmo que seja em uma
pequena fração de tempo, o que chamamos de roubo de ciclo.
Figura 17
Placa-mãe com slots (entradas)
PCI e PCI Express
O Barramento Frontal (FSB – Front Side Bus) é o responsável por
conectar o processador à memória principal. O desempenho do computador
aumenta à medida que há um aumento na taxa de dados
transferida pelo barramento frontal.
Smial/Wikimedia Commons
O Barramento de Interconexão
de Componente Periférico (PCI –
Peripheral Component Interconnect)
é o responsável pela conexão dos
dispositivos periféricos – como
placas de vídeo, de som ou de
rede – ao resto do computador.
Uma evolução do barramento PCI
é o barramento PCI Express (PCIe),
que permite a comunicação de
larguras variáveis entre os barramentos
(Figura 17).
72 Sistemas Operacionais
Utilizada na renderização de objetos 3D em tempo real, a Porta
Gráfica Acelerada (AGP – Accelerated Graphics Port) é responsável
por conectar placas gráficas que utilizam grandes quantidades de
memória RAM para realizarem suas atividades.
O barramento Universal Serial Bus (USB) – Barramento Serial Universal
– foi criado para realizar a conexão dos dispositivos de E/S,
considerados lentos, como mouses e teclados, ao computador. Uma
grande vantagem na sua utilização é que os dispositivos
USB fazem uso do mesmo driver, portanto
não é necessário instalar um novo driver cada vez
que um novo dispositivo USB é acoplado ao computador,
nem mesmo reiniciar a máquina. A logo
utilizada para representar barramento USP é apresentada
na figura ao lado.
O barramento Small Computer System Interface
(SCSI) – Interface de Pequeno Sistema de Computadores – foi criado
para a conexão de dispositivos de alto desempenho e alto consumo
de banda, como os discos rígidos rápidos,
os scanners etc. O barramento SCSI
é utilizado pela Apple, desde os primeiros
computadores Macintosh, por computadores
que fazem uso do sistema
operacional UNIX e por computadores
baseados na arquitetura Intel (Figura
19).
Por último, vamos abordar o barramento
Instituto de Engenheiros Elétricos
e Eletrônicos 1394 (IEEE) – Institute
of Electrical and Electronic Engineers –, conhecido comercialmente
como FireWire (Figura 20), nome comercial dado pela Apple. Como
o USB, o IEEE 1394 efetua a transferência de dados de
modo serial, porém alcançando velocidades superiores
às do USB, permitindo seu uso na transferência
de arquivos e dados em câmeras digitais, players
multimídia etc. O IEEE 1394 não faz uso
de um controlador central.
Figura 18
Logo do USB
Figura 19
Conectores SCSI
Smial/Wikimidia Commons
Figura 20
Conectores FireWire
Interação do sistema operacional com hardware e software 73
2.7.2 Dispositivos de E/S
Segundo Tanenbaum e Bos (2015), um dispositivo de E/S é constituído
por duas partes, um controlador, isto é, um chip ou um conjunto
de chips responsável pelo gerenciamento do dispositivo, e o dispositivo
propriamente dito. O sistema operacional se comunica com o controlador,
solicitando a ele que os dados sejam lidos pelo dispositivo, quando
é realizada uma operação de entrada, ou enviados para o dispositivo,
quando é realizada uma operação de saída.
No princípio da computação, os dispositivos de E/S se limitavam à
leitura de cartões perfurados, um dispositivo de entrada, e à impressora,
um dispositivo de saída. Com a evolução dos computadores e o surgimento
de novos dispositivos, surge a necessidade de padronização
na interface dos dispositivos de E/S, pois isso permite que, ao acoplarmos,
por exemplo, um disco rígido ao computador, este seja reconhecido
pelo controlador, com o qual o sistema operacional se comunicará.
A comunicação do dispositivo de E/S com o controlador é feita por um
software conhecido como driver do dispositivo. Cabe ao fabricante de
um dispositivo fornecer um driver específico para cada sistema operacional
suportado por ele. Por exemplo, ao comprar uma impressora,
ela virá acompanhada de drivers que permitirão a sua instalação em
diferentes sistemas operacionais, como Windows, Linux ou macOS, sistema
operacional utilizado pelos computadores da Apple.
Segundo Tanenbaum e Bos (2015), todo controlador tem um pequeno
número de registradores usados na comunicação. Na prática,
o sistema operacional envia um comando para o driver, o qual ativa o
controlador, traduzindo o comando recebido, para que este possa ser
gravado nos registradores do dispositivo. O conjunto de registradores
do dispositivo é chamado espaço de porta de E/S.
A arquitetura de alguns tipos de computadores permite que os registradores
dos dispositivos sejam mapeados como espaços de endereçamento
para o sistema operacional, permitindo que as instruções
sejam lidas e escritas, como o que acontece na memória principal. Essa
abordagem elimina a necessidade de instruções especiais de E/S. Já em
outros computadores, os registradores foram colocados no espaço de
portas de E/S, no qual instruções especiais IN e OUT estão disponíveis
em modo núcleo para serem utilizadas pelos drivers. Essa abordagem
não faz uso de espaço de endereçamento, como a primeira, mas necessita
que as instruções especiais IN e OUT sejam reconhecidas.
74 Sistemas Operacionais
CONSIDERAÇÕES FINAIS
Neste capítulo, aprofundamos a nossa visão sobre os arquivos e diretórios,
que estão presentes em nossos computadores. O que para nós
parece simples, para o sistema operacional representa um conjunto de
tarefas e preocupações com a segurança.
Também adentramos no mundo dos componentes do computador,
que são parceiros do sistema operacional na sua incansável tarefa de realizar
as solicitações feitas pelo usuário, além de realizar tarefas vitais, das
quais não tomamos conhecimento. O que aos nossos olhos pode levar
alguns segundos, como o ato de ligar um computador apertando um botão,
internamente aciona um batalhão de componentes, liderados pelo
sistema operacional.
ATIVIDADES
1. Qual é a maneira mais simples de se armazenar um arquivo em um
sistema operacional?
2. Qual é a finalidade dos arquivos especiais de caracteres no sistema
operacional UNIX?
3. Qual é a finalidade dos arquivos especiais de blocos no sistema
operacional UNIX?
4. O que você compreende por diretório-raiz?
5. Quais são as vantagens na utilização do firmware?
REFERÊNCIAS
DEITEL, H. M.; DEITEL, P.; CHOFFNES, D. Sistemas operacionais. 3. ed. Trad. de Arlete Simille
Marques. São Paulo: Pearson, 2005.
TANENBAUM, A. Organização Estruturada de Computadores. 6. ed. São Paulo: Pearson
Universidades, 2013.
TANENBAUM, A.; BOS, H. Sistemas Operacionais Modernos. 4. ed. São Paulo: Pearson
Universidades, 2015.
Interação do sistema operacional com hardware e software 75
3
Processos e threads
As solicitações feitas por usuários e as aplicações em execução
convertem pedidos em processos que são monitorados pelo
sistema operacional e disputam um tempo de acesso na Unidade
Central de Processamento (Central Processing Unit – CPU). Com
a disseminação dos computadores, os sistemas monoprocessados
se tornaram multiprocessados e, com isso, a forma como os processos
eram executados também precisou mudar, sendo criados
os threads, que aceleram a execução do processo como um todo.
Neste capítulo, abordaremos a definição de processos, seus
possíveis estados, sua forma de gerenciamento, a definição de
interrupções e como se dá a comunicação entre processos.
Estudaremos, também, a definição de threads, os seus possíveis
estados, as operações que podemos realizar com eles, os seus
modelos e suas formas de implementação. Discutiremos sobre
formas de execução assíncrona concorrente e programação concorrente.
Vamos entender o problema computacional conhecido
como deadlock e quais são as técnicas de escalonamento utilizadas
pelo processador.
Ainda, trataremos do termo CPU como sinônimo de processador,
utilizando ambos os termos com igual significado.
3.1 Processos
Vídeo Com o decorrer do tempo, os computadores passaram a executar
várias operações ao mesmo tempo. O que era feito de uma maneira
sequencial, passou a ser realizado simultaneamente, mesmo que isso
não chame a atenção do usuário.
Isso se deu graças à evolução dos processos, o que permitiu aos
sistemas operacionais a capacidade de executar e monitorar as ativi-
76 Sistemas Operacionais
dades de maneira simultânea. As operações realizadas pelo usuário, as
aplicações, os dispositivos e o próprio sistema operacional existem na
forma de processos; eles podem ser criados, destruídos, bloqueados e
ativados a todo momento.
3.1.1 Definição de processo
Conforme Deitel, Deitel e Choffnes (2005), a primeira vez em que o
termo processo foi utilizado ao se referir a sistemas operacionais foi no
desenvolvimento do sistema operacional MULTICS – sinônimo de tarefa
(job). Ele também pode ser definido como um programa em execução.
Um processo possui o seu próprio espaço de endereçamento,
composto de três regiões: uma região de texto, onde é armazenado o
código a ser executado pelo processador; uma região de dados, onde
são armazenadas as variáveis e a memória, que é alocada dinamicamente
durante a execução do processo; e uma região de pilha, onde
são armazenadas as instruções e as variáveis locais para as chamadas
ativas do procedimento, que fazem a pilha crescer quando são emitidas
e diminuem quando o procedimento retorna às chamadas.
3.1.2 Estados de processo
Uma das responsabilidades do sistema operacional é garantir que
cada processo tenha acesso à mesma quantidade de tempo de uso de
CPU. Entretanto, o número superior de processos, comparado ao número
de CPUs disponíveis, somado à concorrência na execução dos processos,
faz com que o trabalho do sistema operacional seja mais difícil.
Em virtude dos eventos a que está sujeito, um processo usa diferentes
estados, como: o estado de execução, que indica que um processo
está sendo executado pelo processador; o estado “de pronto”, no qual
o processo informa ao sistema operacional que já pode ser executado
e está aguardando por um processador que esteja disponível; e o estado
bloqueado, quando o processo está aguardando pela finalização de
um evento, por exemplo, uma requisição de E/S para prosseguir com
sua execução.
Cabe ao sistema operacional conhecer os processos e seus respectivos
estados. Para realizar essa tarefa, ele utiliza duas listas, uma que
armazena os processos em estado de pronto, lista de prontos; e outra
que armazena os processos em estado bloqueado, lista de bloqueados.
Elas se diferenciam pela forma com a qual os processos são ordenados,
Processos e threads 77
os processos da lista de prontos são armazenados de acordo com a sua
prioridade, da mais alta para a mais baixa. Isso garante que, quando
um processador for liberado, o próximo processo, com prioridade mais
alta, na lista de prontos, será executado. Já na lista de bloqueados, a
ordenação não é importante, pois os processos, armazenados na lista,
são liberados à medida que os eventos, que eles estão esperando, são
realizados.
3.1.3. Gerenciamento de processo
Os sistemas operacionais são responsáveis pelos processos, prestando
serviços essenciais a eles, como criação, destruição, suspensão,
retomada, mudança de prioridade, bloqueio, ativação e a comunicação
interprocessos (Interprocess Communication – IPC).
3.1.3.1 Estados de processo e estados de transição
A lista de prontos recebe processos de acordo com o que um usuário
executa de programas em seu computador. Ao encontrar um processador
disponível para executá-los, os processos vão galgando posições na
lista de prontos, deixando o estado de pronto para o estado de execução,
sofrendo uma transição de estado. Cabe a uma entidade do sistema
operacional, chamada despachante, a responsabilidade de indicar
ao processo, que ocupa a primeira posição na lista de prontos, que ele
pode fazer uso de um processador, recebendo essa atividade o nome
de despacho.
1
Um quantum corresponde ao
tempo limite de utilização do
processador por um processo,
equivalendo a 100 e 300.
O sistema operacional controla as transições de estado, possibilitando
que o maior número de processos possível possa acessar os processadores
disponíveis no computador. Esse controle permite que um
processador seja alocado por um processo indefinidamente, não cedendo
lugar para os demais que estão na fila de pronto. Para evitar que isso
ocorra, o sistema operacional utiliza um timer, isto é, um temporizador
de intervalo que permite que um processo seja executado durante um
intervalo de tempo específico, chamado quantum 1 . Caso o processo não
libere o processador, após o seu limite de tempo de execução expirar,
o timer cria uma interrupção, permitindo que o sistema operacional recupere
o controle sobre o processador. Esse processo terá o seu estado
alterado de execução para pronto, pelo sistema operacional, que também
mudará o estado do primeiro processo da fila de pronto para execução,
iniciando de novo o timer. Dizemos que um processo mudou seu estado
78 Sistemas Operacionais
de execução para bloqueado, quando ele está em execução e necessita
realizar uma operação de E/S, por exemplo, e a resposta não chegou
antes do seu tempo de execução terminar; nesse caso, ele devolverá o
controle do processador ao sistema operacional de maneira voluntária.
Ao receber a resposta do dispositivo de E/S, o sistema operacional muda
novamente o estado do processo de bloqueado para pronto, até que ele
possa ser novamente executado.
Para Deitel, Deitel e Choffnes (2005), há quatro estados de transição
possíveis, conforme a Figura 1.
Figura 1
Transições de estado de processo
Acordado
Adormecido
1
Despacho
Em
execução
Temporizador
esgotado
2
Bloqueio
3
Pronto
Bloqueado
4
Despertar
Fonte: Deitel; Deitel; Choffnes, 2005, p. 69.
1
Quando um processo é despachado, o sistema operacional muda seu
estado de pronto para execução.
2
Quando o quantum de execução de um processo se encerra e ele conseguiu
realizar a(s) tarefa(s) desejada(s), ele muda de execução para pronto.
3
Quando o quantum de execução de um processo se encerra e ele não
conseguiu realizar a(s) tarefa(s) desejada(s), ele muda de execução para
bloqueado. Essa é a única transição de estado que é feita pelo próprio
processo.
4
Quando um evento que é solicitado por um processo que está no estado
bloqueado se encerra, ele muda de bloqueado para pronto.
Processos e threads 79
Os sistemas operacionais antigos não possuíam timer. Para contornar
essa ausência, os próprios processos em execução liberavam
o processador para um outro processo que estava pronto. Essa estratégia
é chamada de multitarefa cooperativa, que foi abandonada pelos
sistemas operacionais modernos, pois possibilitava que um processo
entrasse em loop infinito ou se recusasse a devolver o processador
para outro processo.
3.1.3.2 Blocos de controle de processo (PCBs)/descritores
de processo
Quando um processo é criado pelo sistema operacional, ele recebe
um número para a sua identificação, o Número de Identificação de Processo
(Process Identification Number – PIN). Ainda, recebe um conjunto
de informações, denominado Bloco de Controle de Processo ou descritor
de processo (Process Control Block – PCB) (Figura 2), que auxiliará o sistema
operacional a gerenciá-lo. Esse conjunto, conforme Deitel, Deitel
e Choffnes (2005), armazena as seguintes informações:
a. O Número de Identificação de Processo (PID).
b. O estado do processo, isto é, se o processo está em execução,
pronto ou bloqueado.
c. Um contador de programa que determina qual será a próxima
instrução executada pelo processo.
d. A prioridade de escalonamento, que indica qual a sua prioridade
de execução.
e. As credenciais, uma listagem dos recursos que poderão ser
acessados pelo processo.
f. O ponteiro para o processo-pai, ou seja, o processo responsável
pela criação do processo.
g. Os ponteiros para os processos-filho, caso o processo venha a
criar outros processos.
h. Os ponteiros para localizar os dados e as instruções do processo
na memória.
i. Os ponteiros para recursos alocados pelo processo, por exemplo,
arquivos.
80 Sistemas Operacionais
j. O contexto de execução, isto é, o conteúdo dos registradores do
processador no qual o processo foi executado por último. Essa
informação é utilizada pelo sistema operacional ao retornar o
processo para o estado execução.
Figura 2
Tabela de processos e blocos de controle de processos
PID
PCB
1
2
.
.
.
n
.
.
.
Contador de programa
Registradores
Estado
Prioridade
Espaço de endereço
Pai
Filhos
Arquivos abertos
...
Bloco de controle de
processo
Outras sinalizações
Contador de programa
Registradores
Estado
Prioridade
Espaço de endereço
Pai
Filhos
Arquivos abertos
...
Bloco de controle de
processo
Outras sinalizações
Contador de programa
Registradores
Estado
Prioridade
Espaço de endereço
Pai
Filhos
Arquivos abertos
...
Bloco de controle de
processo
Outras sinalizações
Fonte: Deitel; Deitel; Choffnes, 2005, p. 70.
Como algumas das informações do PCB precisam ser atualizadas
constantemente pelo sistema operacional, para facilitar sua tarefa,
ele mantém ponteiros para cada um dos PCBs em uma tabela de processos,
que pode ser única para todo o sistema operacional ou gerada
para cada um dos usuários. A tabela de processos permite que o sistema
operacional acesse mais rapidamente os PCBs.
Quando um processo é encerrado, voluntariamente ou não, o sistema
operacional retira o registro desse processo da tabela de processos,
disponibilizando os recursos que ele estava utilizando e liberando-os
para outros.
Processos e threads 81
3.1.3.3 Operações de processo
E
Figura 3
Hierarquia na criação de
processo
B
A
C
F
D
G
De acordo com Deitel, Deitel e Choffnes (2005), as operações de processo,
que estão sob responsabilidade do sistema operacional, no que
se refere a processos, são: criação, destruição, suspensão, alteração,
alteração da prioridade de execução, bloqueio, despacho e permitir
que um processo se comunique com outro. Um software em execução,
isto é, um processo, consegue gerar novos processos. Quando isso
ocorre, ele passa a ser chamado de processo-pai; e os processos que
são criados por ele passam a ser chamados de processos-filho, que não
podem possuir mais de um processo-pai, conforme a Figura 3. Com o
encerramento de um processo, de maneira voluntária ou pelo sistema
operacional, caso ele possua processos-filho, dependendo da situação,
o sistema operacional pode destruir todos os seus descendentes ou
permitir que eles continuem existindo, mesmo depois que o processo-
-pai tenha sido desfeito.
H
I
O Linux, que se baseia no UNIX, cria um processo chamado init
(Figura 4) quando o core (núcleo) do sistema operacional é inicializado.
O init gera vários processos-filho, como:
Fonte: Deitel; Deitel; Choffnes, 2005, p. 71.
O processo kswapd,
responsável por
operações de
gerenciamento de
memória.
O processo xfs,
responsável por
operações do sistema
de arquivos.
O processo klogd,
responsável pela
leitura das mensagens
de log do kernel do
sistema operacional.
A
C
E
B
D
O processo khubd,
responsável por
operações de
dispositivos.
O processo login,
responsável pela
autenticação dos
usuários no sistema
operacional.
82 Sistemas Operacionais
Figura 4
Hierarquia de processo LINUX
init
kswapd
khubd
pdflush
login
xfs
klogd
bash
vi
myprog
finger
Fonte: Deitel; Deitel; Choffenes, 2005, p. 72.
Cabe ao sistema operacional realizar as operações sobre os processos
em seus diferentes estados, gerenciando seu ciclo de vida e sua
hierarquia.
3.1.3.4 Suspender e retomar
Para detectar possíveis ameaças à segurança, ou para depuração
(debug) do software em execução, os sistemas operacionais permitem
aos administradores, usuários e processos realizarem a suspensão de
um processo. Quando isso ocorre, ele não é destruído, mas retirado
da disputa pelo tempo de execução na CPU sem previsão de retorno.
Um processo pode suspender a si mesmo ou ser suspenso por outro
processo. Contudo, quando um processo está suspenso, ele somente
poderá ser retomado por outro processo.
Quando um processo está em execução e suspende a si mesmo, ele
passa para o estado suspenso-pronto, que posteriormente será alterado
para pronto. Quando a suspensão é feita por um outro processo, temos
duas opções: se o processo suspenso estiver no estado pronto, o seu
estado mudará para suspenso-pronto; porém, se ele estiver no estado
bloqueado, o seu estado mudará para suspenso-bloqueado, conforme
demonstrado na Figura 5.
Processos e threads 83
Figura 5
Transições de estado de processo com suspensão e retomada
Conclusão e E/S ou
conclusão de evento
Pronto
Bloqueado
Suspender
(b)
Temporizador
esgotado
Retomar
(a)
Despachar
Em
execução
Espera de E/S
ou de evento
Suspender
(c)
Retomar
Estados
ativos
Suspender
Suspenso-
-pronto
Conclusão de E/S ou
conclusão de evento
Suspenso-
-bloqueado
Estados
suspensos
Fonte: Deitel; Deitel; Choffnes, 2005, p. 73.
Quando o processo está no estado suspenso-bloqueado, temos duas
opções para sair: ele pode ter seu estado mudado para bloqueado novamente,
ou o evento de E/S que o tornou bloqueado pode ser finalizado
e, assim, ele passa de suspenso-bloqueado para suspenso-pronto e
aguarda sua promoção para pronto.
3.1.3.5 Chaveamento de contexto
Dizemos que um sistema operacional realiza um chaveamento de
contexto quando ele interrompe a execução de um processo e começa
a executar outro que estava no estado pronto. Quando isso ocorre,
o sistema operacional salva o contexto de execução do processo que
estava no estado execução no PCB desse processo. Além de carregar o
contexto de execução anterior do processo que estava no estado pronto,
também em seu PCB. Cabe ao sistema operacional tornar essa operação
transparente para os processos, que não percebem que tiveram
o seu uso do processador paralisado (Figura 6).
84 Sistemas Operacionais
Figura 6
Chaveamento de contexto
Processo P 1
executa
no processador
Processador
Memória principal
Após uma interrupção,
o núcleo decide
despachar um novo
processo e inicia um
chaveamento de
contexto
Processo P 2
executa
no processador
P 1
Processador
P 1
Processador
P 2
O núcleo armazena o
contexto de execução
do Processo P 1
em seu
PCB na memória
O núcleo carrega o
contexto de execução
do Processo P 2
do seu
PCB na memória
PCB do
processo
P 1
PCB do
processo
P 2
Fonte: Deitel; Deitel; Choffnes, 2005, p. 74.
O motivo do sistema operacional realizar o chaveamento de contexto
é que ele precisa que o processador realize tarefas, consideradas
por ele essenciais, e não as tarefas designadas por um processo.
Cabe ao sistema operacional minimizar o tempo e a utilização desse
recurso. Em algumas arquiteturas, como a Intel Architecture 32-bits
(IA-32 – i386), o próprio processador realiza o chaveamento de contexto,
manipulando o PCB dos processos sem a interferência do sistema
operacional.
3.1.4 Interrupções
Para Deitel, Deitel e Choffnes (2005), as interrupções habilitam o
software a responder aos sinais do hardware. Para poder gerenciar
melhor as interrupções, o sistema operacional usa um conjunto de
instruções, chamado tratador de interrupção, no qual ele armazena a
resposta para cada tipo de interrupção que pode ocorrer, controlando
melhor o processador.
Chamamos de desvio (trap) quando uma interrupção é gerada pelo
processador com base nas instruções de um processo que está sendo
executado. O desvio é uma operação síncrona, isto é, o receptor e
o emissor precisam permanecer on-line durante toda a comunicação.
Um trap ocorre quando um processo tenta realizar uma ação ilegal,
como acessar uma área de memória que esteja protegida.
Processos e threads 85
Uma interrupção também pode ser iniciada por algum evento que
pode ou não estar relacionado à execução de um processo. Quando
isso ocorre, ela é considerada assíncrona, ou seja, o emissor e o receptor
não necessitam permanecer on-line durante toda a comunicação.
Uma interrupção assíncrona ocorre quando o usuário pressiona uma
tecla no seu teclado ou movimenta o mouse.
Para o sistema operacional, o uso de interrupções é uma forma
simples e barata de chamar a atenção do processador. Uma possível
alternativa para substituir as interrupções é fazer uso da sondagem
(polling), na qual o próprio processador solicita a cada um dos dispositivos
o seu status. A sondagem é viável somente quando estamos
tratando de sistemas com baixa complexidade, pois isso consumiria
muito tempo e esforço por parte do processador para obter os status
de todos os dispositivos em uso.
Mesmo diante dessa vantagem, não podemos dizer que o uso de
interrupções é perfeito. Isso porque se o número de interrupções aumentar
desproporcionalmente, o sistema operacional pode encontrar
dificuldades para acompanhar e executar todas elas. Para evitar
uma possível perda de informações, os sistemas adotam medidas, por
exemplo, ao receber um pacote de dados, o sistema de redes prontamente
gera uma interrupção para informar ao processador sobre o
pacote recebido que está pronto para ser processado. Entretanto, em
alguns casos, o processador não está disponível para atender a essa
interrupção no momento. Assim, cabe ao sistema armazenar os dados
ainda não processados em memória, minimizando a sua perda.
Ao receber uma interrupção, o processador precisa gravar os dados
do processo em execução para que ele possa recuperá-lo e executá-lo,
depois de estar liberado da atividade vinculada à interrupção. Esses dados
costumavam ser gravados em uma estrutura de dados, conhecida
como Palavra de Estado de Programa (Program Status Word – PSW). Já
nos computadores que usam a arquitetura IA-32, a estrutura de dados
recebe o nome de Segmento de Estado de Tarefa (Task State Segment –
TSS). Cabe ao sistema operacional decidir se o processo interrompido
ou outro processo será executado pelo processador quando ele estiver
liberado.
Segundo Deitel, Deitel e Choffnes (2005), a arquitetura IA-32 pode
receber dois tipos de sinais diferentes: as interrupções, que informam
86 Sistemas Operacionais
ao processador que um evento ocorreu, como o término do quantum
do processo em execução, a conclusão de uma comunicação com um
dispositivo de E/S ou uma interrupção gerada por um processo; e as
exceções, que indicam a existência de possível erro, seja ele de hardware,
seja de software. Cabe ao sistema operacional estar atento às
interrupções, identificando a sua origem e dando continuidade para a
ação que ela informa, bem como corrigindo possíveis erros reportados
pelas exceções.
3.1.5. Comunicações interprocessos
Os ambientes de multiprogramação e os ambientes de rede obrigaram
os sistemas operacionais a criarem formas de comunicação
interprocessos (IPC) que garantem a coordenação (sincronização) das
atividades dos processos fazendo uso de sinais e trocas de mensagem
para eles se comunicarem entre si. Isso permite a um usuário, por
exemplo, enviar um documento a uma impressora que faz parte da sua
rede ou acessar, via browser, uma página Web, que está hospedada em
um servidor da internet.
3.1.5.1 Sinais
Sinais são interrupções de software que notificam ao processo que
um evento ocorreu. Eles não permitem que os processos troquem dados
entre si. Fica sob responsabilidade do sistema operacional determinar
qual processo deverá receber o sinal e como ele será respondido pelo
processo que o recebeu (DEITEL; DEITEL; CHOFFNES, 2005).
Ao receber um sinal, os processos podem: capturá-lo, quando o
processo especifica uma rotina utilizada pelo sistema operacional para
emitir o sinal; ignorá-lo, quando o processo depende de uma ação-
-padrão realizada pelo sistema operacional para que o sinal recebido
possa ser tratado; ou mascará-lo, quando o processo informa ao sistema
operacional que não deseja mais receber sinais daquele tipo até
que a máscara do sinal seja bloqueada.
3.1.5.2 Troca de mensagens
Com o aumento do interesse pelo uso de sistemas distribuídos,
a IPC passou a ser realizada por trocas de mensagens, que podem ser
Processos e threads 87
unidirecionais, isto é, quando um processo atua como emissor e outro
como receptor da mensagem; ou bidirecional, em que cada um dos
processos pode atuar como emissor ou receptor. As mensagens podem
ter envios bloqueantes (comunicação síncrona) ou envios não bloqueantes
(comunicação assíncrona).
O Linux e o Windows XP usam uma implementação de troca de
mensagens chamada pipe, na qual o sistema operacional usa uma região
na memória que serve como buffer, onde um processo atua como
escritor (emissor), e outro como leitor (receptor).
Nos sistemas distribuídos, as mensagens, ao serem transmitidas,
podem apresentar falhas ou até mesmo se perder no meio da comunicação.
Para tentar evitar esse cenário, eles usam protocolos de
confirmação para garantirem que as mensagens foram recebidas corretamente.
Caso a confirmação não seja recebida pelo processo emissor,
ele poderá esperar um tempo e retransmiti-la. Para eles, outro
problema é a segurança, pois os processos emissores e receptores
poderão identificar possíveis tentativas de roubo de dados feitas por
computadores invasores que não estão devidamente autenticados.
Saiba mais
3.2 Threads
Vídeo
O nome ADA é uma homenagem
a Ada Lovelace, matemática
e escritora inglesa, considerada a
primeira programadora.
Mesmo que os sistemas operacionais permitissem que vários programas
fossem executados simultaneamente nos computadores mais
antigos, as linguagens de programação utilizadas naquela época não
possuíam esse recurso de maneira nativa. A linguagem de programação
ADA, desenvolvida pela Bull SAS para o Departamento de Defesa
dos EUA na década de 1970, foi uma das primeiras linguagens de programação
a dar suporte à programação concorrente.
As linguagens de programação atuais, como Java, C#, Python etc.,
utilizam a tecnologia multithread, que permite aos programadores desenvolverem
aplicativos que serão executados de maneira concorrente.
3.2.1 Definição de threads
Um thread permite ao sistema operacional executar uma tarefa de
modo independente dos outros processos ou threads, sendo chamado
de processo leve (Lightweight Process – LWP). Apesar dessa independência,
os threads são criados com base em processo tradicional, cha-
88 Sistemas Operacionais
mado de processo pesado (Heavyweight Process – HWP). Threads usam
um subconjunto dos recursos utilizados por um processo comum, como:
os registradores, a pilha e os Dados Específicos de Threads (Thread-Specific
Data – TSD). O espaço de endereço e outras informações globais são
compartilhadas pelos threads com o processo pesado (Figura 7).
Figura 7
Relação entre thread e processo
Processo pesado
Informação global
para todos os
threads de um
processo
Espaço de endereçamento
Outros dados globais de processo
Registradores
Registradores
Registradores
Informação local
para cada thread
Pilha
Máscara
Pilha
Máscara
Pilha
Máscara
TSD
TSD
TSD
Threads
Fonte: Deitel; Deitel; Choffnes, 2005, p. 90.
O gerenciamento de threads pode ser realizado pelo software do
usuário ou pelo sistema operacional que utiliza bibliotecas para garantir
que isso ocorra, como: Win32, utilizada pela Microsoft nas versões
do Windows 32 bits; C-threads, utilizada nos sistemas operacionais Macintosh
OS X, Solaris e Windows NT; PThreads, definida pelo padrão
POSIX (Portable Operating System Interface – Interface Portável entre
Sistemas Operacionais) do UNIX e os sistemas com base nele.
O padrão POSIX, desenvolvido pelo Instituto de Engenheiros Eletricistas
e Eletrônicos (Institute of Electrical and Electronics Engineers
– IEEE), é uma especificação que busca definir padrões para que os sistemas
operacionais sejam compatíveis entre si. Ele define uma API, os
shells de linha de comando e as interfaces dos aplicativos para o UNIX
e os sistemas com base nele.
O uso de threads acabou se tornando relevante por vários motivos,
entre eles podemos citar: o projeto de software, que tem como base o
desenvolvimento modular do software e a evolução dos compiladores,
que possibilitaram a criação de trechos do código-fonte, que podem
Processos e threads 89
ser executados separadamente da aplicação, fazendo uso de threads;
o desempenho, que permite às aplicações multithread fazerem uso de
um ou de vários processadores paralelamente, diminuindo significativamente
o tempo de execução da aplicação; e a cooperação, que permite
a IPC pelos threads, o que minimiza o uso de memória, pois passa
a utilizar o endereço de memória compartilhado pelo processo pesado.
Quando um thread é criado, o sistema operacional não necessita
inicializar os recursos compartilhados entre ele e o processo pesado.
Isso reduz o esforço na criação e encerramento dos threads, quando
comparados ao de um processo.
3.2.2 Estados de threads
Assim como os processos, todo thread pode passar por uma série
de estados (Figura 8). Quando criamos um thread com a linguagem
de programação Java, ele está no estado nascido (born), permanecendo
assim até que o programa o inicie e passe para o estado pronto
(runnable – executável). Quando ele tem acesso a um processador e
começa a ser executado, muda para o estado em execução. Finalmente,
indo para o estado morto (dead), que é quando termina sua tarefa ou é
encerrado, liberando seus recursos no sistema.
Figura 8
Ciclo de vida de um thread
nascido
Iniciar
Notificar ou acordar
Esperar por evento
Dormir
Preempção
pronto
em
execução
Concluir
Despacho
Emitir requisição
de E/S
Conclusão de E/S
em espera adormecido morto bloqueado
Intervalo de sono expira
Fonte: Deitel; Deitel; Choffnes, 2005, p. 93.
90 Sistemas Operacionais
Quando precisa aguardar pela conclusão de uma requisição para
um dispositivo de E/S, o thread passa para o estado bloqueado; retornando
ao estado pronto somente quando a requisição tiver sido encerrada.
Quando precisa esperar por um evento, como o sinal de outro
thread, ele passa para o estado em espera, trocando para o estado
pronto, quando é acordado, isto é, quando recebe uma notificação de
outro thread. Quando não possuem nenhuma atividade para realizar,
logo, não necessitam utilizar o processador por um intervalo de tempo,
chamado período de sono, o thread passa para o estado adormecido,
mudando para o estado pronto somente quando o seu período de sono
termina.
3.2.3 Operações de threads
Os threads e os processos possuem muitas operações em comum, porém
os threads possuem algumas operações a mais que os processos,
como: o seu cancelamento, quando uma thread deve ser encerrada, o
que não significa o seu término real, pois ele pode mascarar ou desativar
o recebimento dos sinais de cancelamento; e a sua associação, que acontece
quando um processo ao ser criado inicia um thread primário, que
será associado a outros threads e fica dormindo até que os outros threads
encerrem sua execução. O Windows XP utiliza essa operação.
3.2.4 Modelos de threads
Apesar de a forma de se implementar threads variar entre os sistemas
operacionais, na sua grande maioria, eles utilizam os três modelos
mais conhecidos: threads de usuário, threads de núcleo e threads de
usuário e de núcleo.
Os threads de usuário (Figura 9) executam operações de suporte
a threads no espaço do usuário, criados por bibliotecas, não podem
executar instruções privilegiadas nem acessar o núcleo (core) do sistema
operacional diretamente. O sistema operacional visualiza todos
os threads que compõem um processo multithread, como apenas um
único bloco de execução, que é despachado de uma só vez, e não por
thread. Isso recebe o nome de mapeamento de thread muitos-para-um.
Como vantagens no uso de threads do usuário, podemos destacar:
não há a necessidade do sistema operacional suportar threads, garan-
Processos e threads 91
tindo portabilidade ao processo; o escalonamento de threads é feito
pelas bibliotecas do usuário, e não pelo sistema operacional; e, como
a sincronização de threads do usuário é feita fora do núcleo (core), ela
não sofre efeito do chaveamento de contexto.
Como desvantagens no seu uso, destacamos: o núcleo (core) do
sistema operacional considera um processo multithread como sendo
um único bloco de execução, isso impede que o sistema operacional
despache threads para serem executados em vários processadores simultaneamente;
outro ponto negativo é que, caso um dos threads realize
uma requisição para um dispositivo de E/S, todo o processo ficará
bloqueado até que a requisição seja encerrada.
Figura 9
Threads de usuário
Um processo
Todos os threads
de um processo
mapeiam para um
único contexto
Espaço do
usuário
Espaço do
núcleo
Thread
Contexto de execução
Fonte: Deitel; Deitel; Choffnes, 2005, p. 95.
Os threads de núcleo (Figura 10) mapeiam cada thread em seu contexto
de execução, procurando solucionar os problemas dos threads
de usuário, fazendo uso do mapeamento de thread um-para-um, no
qual o sistema operacional fornece para cada thread de usuário um
thread de núcleo, que ele conseguirá despachar.
Como vantagens no seu uso, podemos destacar que o sistema
operacional consegue despachar os threads de um processo para
mais de um processador simultaneamente; o sistema operacional
consegue visualizar os threads de modo independente, despachando
os threads que estão no estado pronto, mesmo que um deles
esteja no estado bloqueado.
92 Sistemas Operacionais
Já como desvantagens, podemos destacar que, como o escalonamento
e a sincronização dos threads ficam sob responsabilidade do
núcleo (core) do sistema operacional, os threads de núcleo estão sujeitos
à sobrecarga ocasionada pelo chaveamento de contexto; além
disso, os threads de núcleo são dependentes da API para tratamento
de threads do sistema operacional, perdendo a portabilidade conquistada
pelos threads de usuário.
Figura 10
Threads de núcleo
Um processo
Espaço do
usuário
Cada thread de
usuário mapeia
para um contexto
Espaço do
núcleo
Thread
Contexto de execução
Fonte: Deitel; Deitel; Choffnes, 2005, p. 96.
A combinação de threads de usuário e threads de núcleo (Figura 11)
usa o mapeamento de threads muitos-para-muitos (mapeamento de
threads m-to-n), no qual o número de threads de usuário e threads de
núcleo não precisa ser igual.
Em comparação com o mapeamento de threads um-para-um, o
mapeamento de threads muitos-para-muitos consegue reduzir a sobrecarga
do sistema operacional, implementando um reservatório de
threads (thread pooling), em que a aplicação informa ao sistema operacional
o número de threads de núcleo que precisa.
Essa forma de mapeamento permite que um thread de núcleo,
chamado ativação de escalonador, comunique-se com uma biblioteca
de suporte a threads do usuário que, após a sua ativação (upcall),
passa a realizar o escalonamento dos threads. O mapeamento de
threads muitos-para-muitos é utilizado no Sun Solaris e no Windows
XP.
Processos e threads 93
Figura 11
Modelo de operação de thread híbrido
Processo P 1
Processo P 2
Processo P 3
Espaço do
T 1
T 2
T 3
T 4
T 1
T 2
T 3
T 1
T 2
Cada thread de
núcleo pode mapear
para um ou mais
threads de usuário
usuário
Espaço do
núcleo
Thread
Contexto de execução
Fonte: Deitel; Deitel; Choffnes, 2005, p. 98.
Apresentamos, nesta subseção, os modelos de threads utilizados
pelo sistema operacional. Na próxima subseção, vamos analisar como
os threads são implementados.
3.2.5 Implementações de threads
A execução de um processo pode ser pausada por uma interrupção
gerada por hardware ou por um sinal que, por sua vez, é gerado
por software. Inicialmente projetados para serem utilizados com processos,
os sinais tiveram de ser adaptados para serem utilizados por
threads. Há dois tipos de sinais: o sinal síncrono, que ocorre quando o
sinal é emitido por uma instrução de um processo ou thread em execução;
e o sinal assíncrono, que não está vinculado a um processo ou
thread em execução, como a resposta de uma operação de E/S que
está sendo concluída. O sinal assíncrono deve possuir um identificador
(ID) para definir quem é o receptor da mensagem. Caso o processo
receptor não esteja em execução, o sistema operacional adicionará o
sinal recebido em uma fila de sinais pendentes até que o processo entre
em execução.
Ao receber um sinal assíncrono e o processo fizer uso de threads
na sua execução, o sistema operacional deverá decidir se realizará
94 Sistemas Operacionais
a entrega da mensagem para todos os threads do processo ou para
apenas um deles. Essa estratégia é utilizada pelo UNIX e pela especificação
POSIX.
Os threads que utilizam a API de threads do POSIX são chamados
de PThreads (threads POSIX), que podem ser implementados tanto no
núcleo (core) quanto por bibliotecas do usuário.
O Linux não faz distinção entre processos e threads, por isso os chama
de tarefas. Ele usa a chamada fork, que cria uma tarefa-filha, que
contém todos os recursos (registradores, pilha, espaço de endereçamento)
da tarefa-pai.
Um thread pode chegar ao fim de maneira natural, quando encerra
sua execução; ou de maneira abrupta, quando ocorre uma exceção na
sua execução ou quando recebe um sinal de cancelamento. Cabe ao
sistema operacional, ao identificar o término de um thread, removê-lo
prontamente do sistema.
3.3 Execução assíncrona concorrente
Vídeo Se houver mais de um thread em execução no sistema operacional,
dizemos que esses threads são concorrentes entre si. Eles podem estar
em execução de maneira independente ou cooperativa. Quando a execução
é independente, mas os threads eventualmente se comunicam,
chamamos esse evento de execução assíncrona.
Quando uma aplicação usa uma variável compartilhada, que deve ser
atualizada, por exemplo, por threads concorrentes, o sistema operacional
concede acesso restrito aos threads, isto é, enquanto um thread está
manipulando a variável, os demais precisam esperar (exclusão mútua).
Cabe ao sistema operacional organizar esse processo, limitando o acesso
à variável para apenas um dos threads e enfileirando os demais, que
aguardam a sua vez. Esse processo é chamado de serialização.
O sistema operacional também deve levar em consideração a operação
que estava sendo realizada pelo thread. Quando um thread acessa
uma área que possui dados que podem ser modificados, chamada de
seção ou região crítica, ele deve observar se o thread deseja realizar
uma operação de leitura que não vai, por exemplo, afetar o conteúdo
armazenado. Nesse caso, podemos encontrar threads concorrentes
acessando a mesma região crítica.
Processos e threads 95
Também cabe ao sistema operacional garantir que o acesso à região
crítica por um thread seja o mais rápido possível. Caso o thread
seja encerrado enquanto está realizando o acesso, o sistema operacional
deverá encerrar a exclusão mútua dessa região crítica, para que
ela possa ser acessada por outros threads, essa ação é chamada de
limpeza final.
Segundo Tanenbaum e Bos (2015), quatro condições precisam ser
atendidas para que tenhamos uma boa solução de gerenciamento ao
acesso da região crítica:
a. Dois processos não podem estar acessando simultaneamente as
suas regiões críticas.
b. Não há certeza no que se refere à velocidade e ao número de
CPUs disponíveis.
c. Um processo que está em execução, fora da sua região crítica,
não pode bloquear outros processos.
d. Um processo não pode ficar esperando infinitamente para
acessar a região crítica.
Em um sistema monoprocessado, a solução mais simples para o
gerenciamento de acesso à região crítica é aquela em que o processo
desabilita as interrupções, habilitando-as novamente quando ele sai
dela. Apesar da simplicidade, essa não é considerada uma abordagem
segura, pois o sistema operacional não deve conceder o poder de desligar
as interrupções aos processos dos usuários.
Uma outra abordagem para que o sistema operacional possa gerenciar
a exclusão mútua é o mecanismo de semáforo, proposto por
Edsger W. Dijkstra, cientista da computação holandês, em 1965. O semáforo
possui uma variável protegida, que tem somente um valor.
Quando deseja acessar uma região crítica, um thread utiliza a operação
P (proberen – testar, em holandês) e, quando deseja sair dela, usa
a operação V (verhogen – incrementar, em holandês). Os semáforos
que são utilizados por dois ou mais processos são chamados semáforos
binários.
Caso dois threads tentem chamar a operação P, simultaneamente,
cabe ao sistema operacional garantir que somente um deles tenha
acesso à variável protegida, sendo o outro armazenado na fila de espera,
que usa o algoritmo de ordenação de fila primeiro a entrar, primeiro
96 Sistemas Operacionais
a sair (First In, First Out – FIFO), que possui como vantagem a simplicidade
de ser entendido e a facilidade de ser programado.
Uma outra estratégia é o emprego de um tipo simplificado de
semáforo, chamado mutex (mutual exclusion – exclusão mútua), utilizado
para gerenciar a exclusão mútua de um recurso ou parte de
código compartilhado entre dois processos. Um mutex possui dois
estados, desimpedido ou impedido, podendo ser implementado
com apenas 1 bit. O mutex se diferencia do semáforo porque não
utiliza fila. Quando vários processos ou threads tentam acessar um
mutex que está impedido, eles passam para o estado bloqueado e,
quando o mutex estiver desimpedido, um deles será selecionado
aleatoriamente para utilizá-lo.
Buscando aperfeiçoar e evitar possíveis erros no uso de semáforos,
surgiu o conceito de monitor, uma unidade básica de sincronização de
alto nível que corresponde a uma coleção de rotinas, variáveis e estruturas
de dados agrupadas em um módulo (pacote) que fornece rotinas
de uso para os processos, sem dar acesso às suas estruturas de dados
internas. Ao utilizarmos monitores, somente um processo pode estar
ativo em um monitor em determinado momento.
Quando pensamos em uma CPU, mono ou multiprocessada, as
estratégias citadas anteriormente são válidas. Todavia, elas são ineficientes
quando falamos em sistemas distribuídos, formados por
várias CPUs interligadas por uma rede. Para resolver essa limitação,
surge a estratégia de troca de mensagens (message passing). Enquanto
uma mensagem não chega, o receptor permanece bloqueado
ou emite um código de erro. Para evitar mensagens perdidas, ao
receber uma mensagem, o receptor pode enviar uma mensagem de
confirmação de recebimento (acknowledgement). Uma outra preocupação
está na possível perda da confirmação de recebimento,
que é resolvida com a inclusão de um número sequencial, caso o
receptor receba duas vezes uma mensagem com o mesmo número,
ele descarta o segundo envio. O nome do processo precisa ser único,
para evitar o envio e recebimento de mensagens por processos
errados. Outro ponto importante é a necessidade de autenticação,
para evitar a comunicação com CPUs não autorizadas. Apesar da
versatilidade, a troca de mensagens é mais lenta do que o emprego
de semáforos ou monitores.
Processos e threads 97
Figura 12
Uso de uma barreira
A A A
Processo
B B B
Barreira
C C C
Barreira
Barreira
D D D
Tempo Tempo Tempo
(a) (b) (c)
(a) Os processos se aproximam da barreira. (b) Todos os processos estão prontos e apenas um
deles está bloqueado, impedindo o avanço. (c) Quando o processo deixa de estar bloqueado,
todos eles passam pela barreira.
Fonte: Tanenbaum; Bos, 2015, p. 87.
A última estratégia de sincronização é focada em grupos de processos,
cuja execução das aplicações é dividida em fases e possui como
regra que nenhum dos processos pode mudar de fase antes que todos
o tenham feito. A solução para esse problema é colocar uma barreira
no final de cada fase (Figura 12), na qual todo processo que chegar antes
dos demais é bloqueado, mudando de estado somente quando os
demais o tiverem alcançado.
3.4 Programação concorrente
Vídeo Os programas não concorrentes são mais fáceis de serem escritos,
analisados e modificados do que os programas concorrentes. Porém,
a necessidade de resolver problemas por meio do paralelismo, somada
ao surgimento de sistemas multiprocessados, distribuídos e as arquiteturas
computacionais paralelas, aumentou o uso de programas
concorrentes.
De acordo com Deitel, Deitel e Choffnes (2005), monitor é um objeto
que contém dados e procedimentos necessários para realizar a alocação
de determinado recurso compartilhado ou um grupo de recursos
compartilhados reutilizáveis serialmente. Os dados do monitor somente
são acessados por threads que estão dentro dele, sem a possibilidade
de acesso por threads que estão do lado de fora. Essa técnica é
chamada de ocultação de informações.
98 Sistemas Operacionais
Para que um thread aloque recursos por meio dos monitores, ele
chama uma rotina de entrada de monitor. Caso vários threads tentem
acessar o monitor simultaneamente, o sistema operacional aplica a
exclusão mútua, permitindo que o acesso seja realizado por apenas
um thread de cada vez. Se um thread chama a rotina de entrada do
monitor e não há nenhum thread sendo executado dentro dele, ele
terá acesso ao monitor. Caso contrário, ele terá de esperar até que o
monitor seja destravado. Quando isso ocorre, o monitor cria uma fila
de espera, priorizando os que estão na fila há mais tempo.
Quando um thread, que está dentro do monitor, descobre que não
pode continuar, ele executa um wait sobre uma variável condicional,
informando, por exemplo, que o buffer que ele estava utilizando está
cheio. Ao fazer isso, o thread fica bloqueado, permitindo que outro
thread que está na fila tenha acesso ao monitor. Quando o buffer estiver
vazio novamente, o thread que está em execução emite um sinal,
sai do monitor e permite que o outro thread, até então bloqueado, volte
a ocupar o monitor.
Quando um thread produtor entrega dados para um thread consumidor,
por meio de um buffer em comum, dizemos que eles usam
um buffer circular ou limitado (Figura 13), pois o buffer vai sendo
preenchido pelo thread produtor, eventualmente mais rápido que o
thread consumidor, que vai retirando os dados do buffer gradualmente.
Quando o buffer está cheio, o thread produtor é obrigado a
“dar a volta” no buffer e começar a preenchê-lo novamente desde a
primeira posição. Como os threads podem efetuar suas tarefas com
velocidades diferentes, faz-se necessária uma sincronização eficiente
para que os dois consigam desempenhar suas atividades da melhor
maneira possível.
O buffer circular permite ao thread produtor escrever dados
no buffer, sem ter de esperar que o thread consumidor o retire
em seguida, fazendo uso das entradas vazias do buffer circular.
Isso não impede que o thread consumidor faça a leitura dos
dados na ordem correta e melhore o desempenho do sistema,
pois o thread produtor pode escrever os dados continuamente.
Quanto maior o tamanho do buffer circular, maior a quantidade
de dados que poderá ser escrita pelo thread produtor, antes de o
thread consumidor esvaziá-lo.
Figura 13
Buffer circular
Cburnett/Wikimedia Commons
Processos e threads 99
O buffer circular pode ser utilizado pelo sistema operacional para
gerenciar o controle de spooling, que ocorre quando um thread
(spooler) gera dados que precisam ser impressos por uma impressora,
por exemplo. O spooler escreve os dados no buffer circular, que são
lidos por outro thread (despooler), que os encaminha para a impressora.
Comparando as velocidades desse processo, o spooler é muito mais
rápido do que a impressora, que por sua vez, é mais rápida do que o
despooler.
3.5 Deadlock e adiamento indefinido
Vídeo De acordo com Deitel, Deitel e Choffnes (2005), um processo ou
thread está em estado de deadlock (impasse) ou travado se estiver esperando
por um evento que não vai acontecer.
Um impasse pode ocorrer quando processos disputam recursos,
que podem ser: um dispositivo de hardware, como uma unidade de
disco rígido, ou trecho de informação, como um registro armazenado
em um banco de dados. Segundo Tanenbaum e Bos (2015), um recurso
é algo que pode ser adquirido, usado e liberado com o passar do tempo.
Como podemos observar, há dois tipos de recursos:
a. Preemptível: pode ser retirado do seu processo proprietário
sem prejudicá-lo, como o uso da memória no computador.
b. Não preemptível: não pode ser retirado do seu processo
proprietário sem causar prejuízo à atividade que estava sendo
realizada – por exemplo, quando acaba a luz durante a gravação
de um CD-ROM, comprometendo esta.
Diante dessa caracterização, os impasses ocorrem com recursos
não preemptíveis, visto que os recursos preemptíveis conseguem alocar
recursos de um processo para o outro.
A maioria dos impasses sofridos pelos sistemas operacionais ocorre
pela tentativa de uso de recursos dedicados, também chamados de recursos
reutilizáveis serialmente. Quando um processo necessita fazer
uso de um recurso que não está disponível naquele momento, ele é
bloqueado pelo sistema operacional e, quando o recurso estiver disponível,
será acordado pelo sistema operacional. Em outros casos, ao
se deparar com um recurso indisponível, o processo emitirá um código
de erro.
100 Sistemas Operacionais
Em determinados casos, o uso de recursos é gerenciado por processos
de usuário, como quando o usuário tenta acessar os registros
armazenados em um banco de dados. Uma forma de conceder aos
processos de usuários o gerenciamento dos recursos é fazer uso de
semáforos. Algumas vezes, o processo necessita de dois ou mais recursos,
sendo esses adquiridos de modo sequencial.
Conforme Tanenbaum e Bos (2015), um conjunto de processos entrará
em uma situação de impasse quando todos os processos desse
conjunto estiverem esperando por um evento que somente outro processo
do mesmo conjunto pode realizar. Esse tipo de impasse é denominado
impasse de recurso.
Coffman Jr., Elphick e Shoshani (1971) definiram quatro condições
que podem gerar um impasse de recurso:
a. Condição de exclusão mútua – quando um recurso está
associado a um único processo ou disponível.
b. Condição de posse e espera – em que os processos já estão
fazendo uso de recursos e precisam fazer uso de outros recursos.
c. Condição de não preempção – na qual os recursos que já estão
sendo utilizados por um processo não podem ser tomados dele,
tendo de ser liberados por eles voluntariamente.
d. Condição de espera circular – em que ocorre um encadeamento
circular de processos, que estão esperando pela liberação de um
recurso que está sendo utilizado por outro processo, pertencente
à mesma cadeia.
A forma mais simples com que o sistema operacional pode tratar
um impasse é nomeada de algoritmo do avestruz. Fazendo uso desse algoritmo,
quando o sistema operacional detecta um impasse, bloqueia
o processo solicitante ou emite um código de erro.
Outra abordagem possível é aquela na qual o sistema operacional
não atua na prevenção dos impasses, mas tenta detectá-los quando
acontecem, fazendo uso da CPU, que, a cada determinados minutos ou
quando a sua utilização estiver abaixo do esperado, realiza essa verificação.
Isso pode parecer custoso, porém a existência de impasses no
sistema pode ocasionar a ociosidade da CPU.
Um método utilizado pelos projetistas de sistemas operacionais para
a recuperação de um processo que entrou em um impasse é a geração
Processos e threads 101
de pontos de salvaguardo (checkpoints), que permitem ao processo armazenar
o seu estado (uso de memória e recursos alocados) em um
arquivo, podendo ser reinicializados com base nessa informação.
Ainda, outra abordagem é finalizar um dos processos envolvidos,
esperando que o seu fim permita que os demais processos realizem
suas tarefas, sendo chamada de recuperação por meio de eliminação
de processos.
Uma possível estratégia para evitar a ocorrência de impasses são
as trajetórias de recursos, que têm como base o conceito de estados
seguros, no qual um estado é assim considerado quando ele não está
envolvido em um impasse e caso haja uma ordem de escalonamento
(decisão de quem vai utilizar o recurso ou esperá-lo) para que ele possa
concluir sua execução. Já no estado inseguro, o sistema operacional
não pode garantir que o processo será concluído.
Outra estratégia é fazer uso do algoritmo do banqueiro, desenvolvido
por Dijkstra em 1965, em que um banqueiro (sistema operacional)
de uma cidade pequena consegue atender um grupo de clientes (processos
ou threads) que necessitam de uma linha de crédito (recursos).
Cabe ao banqueiro verificar se o pedido pode levar a um estado inseguro,
o que leva à aprovação ou à recusa do pedido. Ele também precisa
analisar se possui dinheiro suficiente para emprestar aos clientes e a
necessidade de cada um deles. Na prática, esse algoritmo esbarra em
algumas limitações: o número de processos solicitantes é variável, um
processo ou thread não tem conhecimento prévio dos recursos a serem
utilizados e a disponibilidade dos recursos muda muito.
Como as estratégias para evitar a existência de impasses se fundamentam
em dados futuros, desconhecidos pelo sistema operacional,
os projetistas de sistemas operacionais voltaram suas atenções para as
quatro condições definidas por Coffman Jr., Elphick e Shoshani (1971).
Considerando que as soluções propostas para evitar a ocorrência
de impasses não podem ser aplicadas de maneira genérica, algumas
aplicações passaram a fazer uso de algoritmos para resolver problemas
específicos, como:
a. Bloqueio em duas fases (two-phase blocking): atende à
necessidade dos sistemas gerenciadores de bancos de dados
que realizam o bloqueio (lock) de alguns registros para que eles
possam ser atualizados.
102 Sistemas Operacionais
b. Impasse de comunicação: pode ocorrer quando um processo X
envia uma mensagem para o processo Y e fica bloqueado até que
a mensagem de retorno seja recebida.
c. Livelock: pode acontecer quando a tabela de processos do
sistema operacional está cheia e um processo que tenta criar
threads descobre isso. Ele não consegue criar os threads naquele
momento, sendo obrigado a esperar um pouco e fazer uma nova
tentativa. O UNIX e o Windows ignoram o problema de livelock,
uma vez que consideram que sua ocorrência é menos traumática
do que limitar a experiência do usuário.
d. Condição de inanição (starvation): pode acontecer quando um
processo nunca tenha acesso a um recurso que está solicitando.
Sendo um evento possível em qualquer sistema operacional, o impasse
é um assunto discutido desde os primórdios dos sistemas operacionais,
alvo de pesquisa de matemáticos e projetistas de software e
sistemas operacionais.
3.6 Escalonamento de processador
Vídeo Quando um computador possui vários processos ou threads no estado
de pronto e apenas um processador livre para atendê-los, o sistema
operacional precisa usar um escalonador, que usa o algoritmo
de escalonamento para chegar a uma decisão. Esse algoritmo possui
algumas características essenciais, como: justiça, concedendo a cada
processo um tempo considerado adequado para o uso da CPU; aplicação
da política, verificando se a política de escalonamento está sendo
utilizada; e equilíbrio, garantindo que todas as partes do sistema estão
realizando o seu trabalho.
O algoritmo de escalonamento, quando os programas faziam
uso de cartões ou fitas magnéticas, não encontrava dificuldades, em
virtude de sua natureza sequencial, precisando apenas executar o próximo
programa. Com o surgimento dos sistemas multiprogramados,
o algoritmo de escalonamento precisou ser aperfeiçoado para decidir
qual programa teria acesso ao processador.
Segundo Tanenbaum e Bos (2015), o surgimento dos computadores
pessoais trouxe duas mudanças: na maior parte do tempo, existe so-
Processos e threads 103
mente um processo ativo e, com a evolução do hardware, a CPU dificilmente
tem problemas com o consumo de recursos, não ficando mais
limitada ao tempo de processamento, e sim ao tempo com que o usuário
leva para inserir dados, pelo teclado ou mouse. Isso faz com que o
escalonamento não seja considerado importante quando analisamos
computadores pessoais. Entretanto, isso não é verdade quando analisamos
servidores e estações de trabalho (workstations) conectadas
a uma rede em que encontraremos processos internos concorrendo
com aplicações executadas pelos usuários. Cabe ao escalonador escolher
o processo ideal a ser executado, além de garantir o melhor uso
do processador.
Quando falamos de comportamento de processos, encontramos
duas situações: os processos que fazem uso da CPU por um longo tempo
e quase não são afetados por esperas de E/S; e os que vivem uma
situação contrária, com longos intervalos de espera de E/S e pouco
tempo de utilização da CPU.
A decisão do escalonador sobre qual processo será executado deve
ser realizada quando um outro processo está terminando a sua execução.
Ele deve selecionar entre os processos que estão com estado
pronto. Caso não haja nenhum, o processador pode executar um processo
do sistema operacional. Quando um processo em execução é
bloqueado, cabe ao escalonador selecionar um novo processo para
execução. Quando ocorre uma interrupção de E/S, que habilita um processo
que até então estava bloqueado, cabe ao escalonador decidir se
ele será executado ou se um outro processo terá prioridade.
Conforme Tanenbaum e Bos (2015), os algoritmos de escalonamento
podem ser divididos em duas categorias com relação às interrupções
de E/S: na primeira, o algoritmo de escalonamento não preemptivo
escolhe um processo para execução e o executa até que ele seja bloqueado,
para uma requisição de E/S, por outro processo, ou quando
o processo libera a CPU por conta própria; na segunda, o algoritmo
de escalonamento preemptivo escolhe um processo para execução e o
executa por um tempo máximo definido.
Há três categorias de algoritmos de escalonamento: os sistemas em
lote, os sistemas interativos e os sistemas com restrição de tempo real
(TANENBAUM; BOS, 2015).
104 Sistemas Operacionais
Os sistemas em lote são utilizados em empresas que operam com
atividades realizadas periodicamente, como folhas de pagamento, contas
a pagar etc. Neles, não há terminais de usuários aguardando pela
resposta da execução dos processos, logo, os algoritmos de escalonamento
preemptivos e não preemptivos são aceitáveis. Esses sistemas
consideram as seguintes características como essenciais para o algoritmo
de escalonamento: a vazão (throughput), ou seja, a realização do
máximo possível de tarefas por hora; o tempo de retorno, menor tempo
entre o início e o término da execução do processo; e a utilização da
CPU, isto é, minimizar o máximo possível a ociosidade da CPU.
Nos sistemas interativos, em que há usuários interagindo e aguardando
uma resposta, faz-se necessário o uso do algoritmo de escalonamento
preemptivo para evitar que um processo tome o controle
da CPU. Os servidores também se enquadram nessa categoria, pois
atendem a vários usuários, remotos ou não, simultaneamente. Esses
sistemas consideram as seguintes características como essenciais para
o algoritmo de escalonamento: tempo de resposta, proporcionalidade
e satisfação dos usuários.
Já nos sistemas com restrição de tempo real, em que os processos
sabem que não podem ser executados por um longo período, o algoritmo
de escalonamento preemptivo não faz sentido. Esse tipo de sistema
executa somente processos relacionados ao seu propósito. Esses
sistemas consideram as seguintes características como essenciais para
o algoritmo de escalonamento: cumprimento de prazos, evitando que
os dados sejam perdidos durante a execução; e previsibilidade, evitando
perda de qualidade durante a execução do processo.
Ao analisar e procurar soluções para os problemas de sincronização
de sistemas operacionais, foram formulados vários problemas, cujas
soluções são alvo de estudo por parte dos cientistas da computação e
projetistas de sistemas operacionais. Um desses problemas é o produtor-consumidor,
no qual dois processos (produtor e consumidor) compartilham
uma área de tamanho fixo para armazenamento (buffer). O
produtor gera dados e os coloca no buffer sem parar. Simultaneamente,
o consumidor lê os dados, retirando-os de lá um de cada vez. O desafio
proposto pelo problema é garantir que o produtor não vai tentar
adicionar dados no buffer cheio e que o consumidor não tentará ler os
dados do buffer vazio.
Processos e threads 105
Figura 14
Problema dos filósofos glutões,
proposto por Dijkstra
Fonte: Tanenbaum; Bos, 2015, p. 99.
Outro problema conhecido na área é o do jantar dos filósofos,
proposto por Dijkstra em 1965, com o seguinte contexto: cinco filósofos
estão sentados a uma mesa redonda. Cada um deles possui
em sua frente um prato de espaguete. Para poder comer, um filósofo
precisa fazer uso de dois garfos, porém, entre cada par de pratos,
há somente um garfo. Um filósofo ou passa seus dias comendo ou
pensando. Quando ele está com fome, tenta pegar um garfo, depois
o outro. Caso ele consiga fazê-lo, come por tempo determinado, coloca
os garfos de volta na mesa e volta a pensar. O desafio proposto
pelo problema é escrever um programa no qual cada filósofo consiga
realizar suas tarefas sem travamento. A solução para o problema
faz uso de um estado para controlar se um filósofo está comendo,
pensando ou com fome, isto é, tentando pegar os
garfos. Nesse caso, ele pode mudar para estado comendo,
caso os seus vizinhos da esquerda e da direita não estejam
comendo. A solução utiliza semáforos para cada um dos filósofos,
bloqueando os filósofos com fome, caso os garfos dos
seus vizinhos estejam ocupados.
Por último, temos o problema dos leitores e escritores,
proposto por Courtois, Heymans, Parnas (1971) e utilizado
para definir o acesso a sistemas de bancos de dados, com o
seguinte contexto: um sistema de reserva de linhas aéreas
possui vários processos concorrentes, querendo ler e escrever,
simultaneamente. A base de dados pode ser lida por vários
processos ao mesmo tempo, menos quando um processo
estiver escrevendo, o que impede até mesmo a leitura por um outro
processo. O desafio proposto pelo problema é de como programar os
leitores e os escritores. A solução proposta é que quando um leitor
chegar, ele será posicionado depois do escritor, que precisa esperar
pelos leitores que chegaram antes dele, denominada single-writer ou
multi-reader lock. Uma desvantagem nessa solução é que ela não faz
uso de concorrência, portanto, possui um desempenho mais baixo na
sua execução.
Os pesquisadores continuam voltando sua atenção para o escalonamento
de sistemas mono e multiprocessados, porém esse
mesmo interesse não tem sido demonstrado pelos projetistas de
sistemas operacionais, que parecem satisfeitos com os avanços alcançados
até agora.
106 Sistemas Operacionais
CONSIDERAÇÕES FINAIS
Neste capítulo, aprofundamos a nossa visão sobre os processos. A
cada quantum de tempo, eles disputam pela atenção dos processadores,
solicitando recursos, comunicando-se entre si e exigindo atenção por parte
do sistema operacional para que todos eles sejam executados, atendendo
às expectativas do usuário e das aplicações.
Com o aumento dessas expectativas e a evolução do hardware, surgiu
o conceito de paralelismo, que força os processos a se dividirem em
threads, buscando repartir as suas tarefas para maximizar o uso do processador
e minimizar o tempo de execução. Os threads somam-se aos
processos na disputa pela atenção do processador, e a sua existência,
convivência e concorrência passa a ser uma preocupação para os projetistas
e desenvolvedores de sistemas operacionais e software.
ATIVIDADES
1. Do que é formado o espaço de endereçamento do processo?
2. Qual a diferença entre o estado de execução e o estado de pronto de
um processo?
3. Explique o que é o bloco de controle de processo (Process Control
Block – PCB).
REFERÊNCIAS
COFFMAN JR., E. G.; ELPHICK, M. J.; SHOSHANI, A. System Deadlocks. ACM Computing
Surveys, v. 3, p. 67-68, 1971. Disponível em: http://www.ccs.neu.edu/home/pjd/cs7600-s10/
Tuesday_January_26_01/p67-coffman.pdf. Acesso em: 5 ago. 2020.
COURTOIS, P.J.; HEYMANS, F.; PARNAS, D. L. Concurrent control with readers and
writers. Communications of the ACM, v. 14, n. 10, p. 667–668, out. 1971. Disponível em:
https://www.academia.edu/20962701/Concurrent_control_with_readers_and_writers.
Acesso em: 5 ago. 2020.
DEITEL, H. M.; DEITEL, P.; CHOFFNES, D. Sistemas operacionais. 3. ed. Trad. de Arlete Simille
Marques. São Paulo: Pearson, 2005.
TANENBAUM, A.; BOS, H. Sistemas operacionais modernos. 4. ed. São Paulo: Pearson
Universidades, 2015.
Processos e threads 107
4
Memória real e virtual
O simples ato de executar um programa em um computador
esconde várias ações e participantes anônimos, com responsabilidades
bem definidas. O programa é armazenado no disco rígido,
uma unidade de armazenamento secundária, e executado pelo
processador, que não acessa as instruções e os dados diretamente
no disco rígido, pois o considera muito lento. Para aumentar a
velocidade de acesso do processador, o sistema operacional transfere
os dados para a memória principal, servindo como uma área
de depósito mais veloz que o disco rígido. Porém, com o aumento
de tamanho e complexidade dos programas, somado à limitação
no custo da memória principal, os projetistas tiveram de criar a
memória virtual, isto é, páginas armazenadas no disco rígido, as
quais criam a ilusão para o processador de que existe mais memória
no computador do que realmente há.
Neste capítulo, abordamos os seguintes assuntos: conceito,
organização e gerenciamento da memória real; conceito, organização
e gerenciamento da memória virtual; questões de projeto
para os sistemas de paginação; e questões de implementação enfrentadas
pelos projetistas de sistemas operacionais. Além disso,
tratamos da memória real como sinônimo de memória principal.
Essa nomenclatura se faz necessária em função do conceito de
memória virtual.
4.1 Memória real
Vídeo A memória real atua como um depósito de instruções e dados gerados
pelos programas em execução no computador. Ela auxilia o processador
no andamento dos programas e, por ser volátil – isto é, por
perder seus dados quando o computador é desligado –, trabalha com a
108 Sistemas Operacionais
memória secundária (disco rígido) para realizar o armazenamento dos
dados de modo permanente.
A memória real é considerada um dos componentes básicos do
computador. Faz parte da hierarquia de memória e suas principais características
são o tamanho e o custo. Podemos posicioná-la no meio
dessa hierarquia abaixo dos registradores e da memória cache, acima
do disco rígido e de outros dispositivos de memória secundária. A capacidade
da memória real é limitado pelo custo de hardware.
4.1.1 Conceito
A memória real, também conhecida como memória física, memória
principal, memória primária ou, simplesmente, memória, é o único componente
do computador acessado diretamente pela CPU, que lê continuamente
as instruções armazenadas nela e executa-as.
O último estágio na evolução e no aprimoramento da memória real
é a memória de acesso aleatório – Random-Access Memory (RAM) –,
que é pequena, leve e cara. Ela está conectada direta ou indiretamente
à CPU por meio de dois barramentos: um de endereços e um de dados.
A CPU primeiro envia um número pelo barramento de endereços, chamado
de endereço de memória, que indica o local desejado dos dados;
em seguida, lê ou grava os dados nas células de memória pelo barramento
de dados.
4.1.2 Organização
Segundo Deitel, Deitel e Choffnes (2005), historicamente, a memória
real sempre foi considerada um recurso relativamente caro. Mesmo se
levarmos em consideração o declínio do valor de hardware e a evolução
do custo de software, que marcaram a democratização do uso de computadores,
mudando o cenário em que estes eram limitados a poucos,
passando para o uso de computadores pessoais, notebooks, tablets
etc., e mesmo diante da redução de custos, os sistemas operacionais
e as aplicações têm exigido volumes cada vez maiores de memória. O
Windows XP, por exemplo, desenvolvido pelo Microsoft, recomendava
256 MB de memória principal para o seu uso adequado. Sua versão
mais moderna, o Windows 10, recomenda 1 GB, para a versão 32 bits,
e 2 GB, para a versão 64 bits.
Memória real e virtual 109
De acordo com Deitel, Deitel e Choffnes (2005), cabe aos projetistas
de sistemas operacionais tomar algumas decisões sobre a organização
da memória, como:
A
O sistema operacional executará um processo por vez ou
optará pela multiprogramação, na qual vários processos
serão executados simultaneamente?
C
E
B
D
Caso o projetista tenha optado pela
multiprogramação, a memória será dividida em
partes (partições) iguais ou de tamanhos diferentes?
Essas partições serão criadas dinamicamente, de acordo
com a necessidade dos processos, ou estaticamente, com
base em levantamentos estatísticos de comportamento?
Os processos terão de fazer uso de partições
específicas para as quais foram designados ou
poderão fazer uso de partições livres?
Os processos poderão fazer uso de partições contíguas,
isto é, uma do lado da outra, ou poderão ser divididos entre
partições separadas?
Essas são algumas das preocupações dos projetistas de sistema
operacional, no que se refere à utilização e organização da memória
real. Vamos analisá-las nas próximas seções.
4.1.3 Gerenciamento
O sistema operacional faz uso do gerenciador de memória para
organizar e definir as estratégias de gestão de memória, que determinam
qual organização deverá ser utilizada, mediante diferentes cargas
de processos. Ele define a maneira com que o espaço livre é alocado
pelos processos e como atuar diante das possíveis mudanças na utilização
de memória dos processos.
110 Sistemas Operacionais
Figura 1
Organização da hierarquia de memória
Tempo de
acesso ao
armazenamento
diminui
Velocidade
de acesso ao
armazenamento
aumenta
Custo de
armazenamento
por bit aumenta
Capacidade de
armazenamento
diminui
Memória
cache
Memória primária
Armazenamentos secundário
e terciário
Um processador pode
acessar programas e
dados diretamente
O sistema deve primeiramente
transferir programas e dados para
a memória principal antes que um
processador possa referenciá-los
Fonte: Deitel; Deitel; Choffnes, 2005, p. 241.
A Figura 1 apresenta a organização da hierarquia de memória com
base na velocidade e no custo em cada um dos seus níveis, que são
acessados por programas e dados gerenciados pelo sistema operacional.
Buscando obter um desempenho superior ao obtido até então com
a memória primária e com os armazenamentos secundário e terciário,
os projetistas de computadores criaram a memória cache, a qual ocupa
o topo da hierarquia, sendo mais rápida que os seus antecessores
e comunicando-se diretamente com o processador. Ela deu origem a
mais um nível de transferência na execução dos programas, exigindo a
mudança dos programas da memória principal para a cache, antes da
sua execução.
As estratégias de gerenciamento de memória são divididas nas seguintes
categorias:
a. Estratégia de busca: determina qual próxima parte de um
programa ou de um conjunto de dados será transferida para a
memória principal. É dividida em dois tipos: sob demanda, na
qual a transferência ocorre somente quando é referenciada por
um programa em execução; ou antecipada, quando isso é feito
antes de o programa ou os dados serem referenciados.
Memória real e virtual 111
b. Estratégia de posicionamento: estabelece qual lugar da
memória principal deverá ser ocupado pelos programas e
dados que estão chegando. É dividida em três tipos: first fit (FF),
traduzido como primeiro que couber; best fit (BF), ou seja, melhor
que couber; e worst fit (WF), ou pior que couber.
c. Estratégia de substituição: indica quais dados deverão ser
removidos da memória principal para liberar espaço para um
novo programa.
Ao utilizar computadores antigos, os operadores e os primeiros
sistemas operacionais buscavam encontrar uma área na memória
principal contígua que fosse grande o suficiente para acomodar todo
o programa a ser executado. Essa estratégia foi chamada de alocação
de memória contígua e possuía como grande desvantagem o fato de a
memória disponível ser menor do que o programa a ser executado,
inviabilizando o seu andamento. A solução criada pelos projetistas de
software era fazer uso de sobreposições (overlays), as quais permitiam
a execução de programas cujo tamanho era maior que a memória principal,
por meio da divisão do programa em seções lógicas, alocando
a memória conforme a necessidade (Figura 2). Porém, essa estratégia
passou a ocupar muito tempo no processo de desenvolvimento de
software, em virtude do aumento da complexidade dos programas.
Figura 2
Exemplo de sobreposição de memória
0
a
b
Sistema operacional
Parte do código e dos
dados do usuário que
deve permanecer na
memória durante a
execução
1
2
3
Área de
sobreposição
Fase de
inicialização
b
Programa usuário cujos requisitos de
memória são maiores do que a porção
disponível da memória principal
Fase de
processamento
b
b
Fase de
saída
c
1 Carregue a fase de inicialização em b e execute.
2 Depois carregue a fase de processamento em b e execute.
3 Então carregue a fase de saída em b e execute.
Fonte: Deitel; Deitel; Choffnes, 2005, p. 243.
112 Sistemas Operacionais
Outra maneira de acomodação é a alocação de memória não
contígua, na qual o programa é dividido em blocos (segmentos)
para que possa ser disposto em áreas não contíguas da memória
principal. Como vantagem dessa estratégia, o sistema operacional
consegue utilizar pequenas áreas de memória disponíveis, enquanto
a outra modalidade de alocação não conseguia armazenar um
programa inteiro. Como desvantagem, o sistema operacional pode
enfrentar uma sobrecarga, em virtude de um elevado número de
processos tentando acessar a memória principal simultaneamente.
Os primeiros computadores eram monousuários, isto é, atendiam
a um usuário por vez, concedendo a este todos os recursos da máquina.
A Figura 3 exibe a organização de memória em um sistema
monousuário de alocação de memória contígua. Quando os sistemas
operacionais ainda não tinham sido inventados, cabia ao programador
gerar todo o código-fonte da aplicação, bem como as instruções
de E/S.
Figura 3
Alocação de memória contígua em sistemas monousuário
0
a
Sistema operacional
Usuário
b
Não utilizada
c
Fonte: Deitel; Deitel; Choffnes, 2005, p. 243.
Essa realidade mudou quando os projetistas de sistema criaram o
sistema de controle de E/S (Input/Output Control System – IOCS), um
conjunto de rotinas básicas de E/S, as quais eram chamadas pelos programadores,
sem a necessidade de serem reescritas em cada uma das
aplicações, como era feito anteriormente.
Memória real e virtual 113
Uma das preocupações dos projetistas de sistemas operacionais
monousuários era que o sistema operacional não poderia ser
prejudicado pela execução dos programas. Ou seja, caso o sistema
operacional tivesse um mau funcionamento, em virtude de um dos
programas em execução, os demais seriam afetados, pois não conseguiriam
funcionar se o endereçamento de memória utilizado fosse
sobrescrito. Como solução para essa possível ameaça, foi implementado,
dentro do processador, o registrador de fronteira (Figura 4),
que armazena o endereço de memória destinado ao programa do
usuário – endereço esse que é validado a cada requisição de alocação
de memória.
Figura 4
Uso do registrador de fronteira para proteger o sistema operacional
0
a
Sistema operacional
Processador
Registrador de
fronteira
a
Usuário
b
O sistema impede o
usuário de acessar
endereços menores do
que a
c
Não utilizada
Fonte: Deitel; Deitel; Choffnes, 2005, p. 244.
A execução dos primeiros sistemas monousuários de memória real
exigia um tempo de preparação maior do que o de execução do job,
pois era necessário o carregamento do sistema operacional, a montagem
das fitas e pilhas de discos, a preparação da impressora, a entrega
dos cartões perfurados etc. Após a execução, o que havia sido montado
previamente deveria ser desmontado, sendo esse intervalo chamado
de tempo de desmontagem (teardown time). Como estamos tratando de
sistemas monousuários, e a execução de um novo job necessitaria de
uma nova preparação, o computador ficava ocioso entre o tempo de
preparação e o de desmontagem.
114 Sistemas Operacionais
No intuito de reduzir esse tempo ocioso, os projetistas de sistemas,
no início da década de 1960, desenvolveram o processamento
em lote. Nesse sistema, os jobs eram agrupados em lotes, por meio
de uma linguagem de controle de jobs, e armazenados no disco rígido
ou na fita magnética. Desse modo, eram lidos por um processador de
fluxo de jobs, que assumia algumas das responsabilidades antigamente
executadas pelo operador manualmente, ficando sob os cuidados
deste apenas a limpeza e preparação para a execução do próximo job.
Para melhorar o desempenho dos sistemas operacionais monousuários,
os projetistas criaram os primeiros sistemas que faziam uso de
multiprogramação por partição fixa, em que a memória principal era
dividida em partições de tamanho fixo, armazenando um job em cada
uma delas e criando para o usuário a ilusão de que os seus processos
estavam sendo executados em paralelo. A multiprogramação aumentou
o risco de alocação de memória dos sistemas monousuários, pois
neles o sistema operacional deveria ser protegido da execução de apenas
um programa; agora, o sistema operacional deveria ser protegido
de vários programas em execução, e esses deveriam ser protegidos
deles mesmos. O que era controlado por somente um registrador de
fronteira passou a fazer uso de vários deles, um para cada partição,
executando o controle de baixo (de base) e do alto (de limite).
Outro problema encontrado pela multiprogramação por partição fixa
é a fragmentação interna, quando o programa faz uso de uma quantidade
de memória menor do que a partição, levando ao desperdício de
espaço. Como resposta, os projetistas abandonaram as partições de tamanho
fixo e passaram a permitir que os processos fizessem uso da
quantidade de memória necessária, respeitando a quantidade de memória
total disponível. Essa estratégia foi chamada de multiprogramação
por partição variável. Ela não sofre fragmentação interna, pois o processo
faz uso de uma partição do tamanho definido por ele. Porém, conforme
os processos vão encerrando a sua execução e liberando a memória,
eles vão deixando lacunas (holes) na memória principal (Figura 5), que
podem ser pequenas demais para armazenar outro processo, ocasionando
uma fragmentação externa. Esta ocorre quando a soma de todas
as lacunas é grande o suficiente para acomodar um processo, mas
cada uma delas é pequena demais para fazer o mesmo.
Memória real e virtual 115
Figura 5
Espaços (lacunas) na memória principal em virtude da multiprogramação por partição variável
Sistema operacional
Sistema operacional
Sistema operacional
P 1
P 1
P 1
P 2
P2 termina
e libera sua
memória
Lacuna
Lacuna
P 3
P 3
P 3
P 4
P 4
P4 termina
e libera sua
memória
Lacuna
P 5
P 5
P 5
Lacuna
Lacuna
Lacuna
Fonte: Deitel; Deitel; Choffnes, 2005, p. 251.
Para evitar a fragmentação externa, o sistema operacional verifica
se existe alguma partição livre e adjacente à lacuna. Se sim, ele transforma
essas duas partições em uma maior, que poderá acomodar um
processo. Outra estratégia é a compactação de memória, na qual as
áreas ocupadas são enviadas para uma das extremidades da memória
principal, criando uma grande área livre e contígua. Esse processo
de compactação é chamado de coleta de lixo (garbage collector), que
possui como desvantagem a necessidade de realocar os processos em
execução e impedir que novos processos sejam inicializados durante a
compactação.
Cabe ao sistema operacional definir a estratégia de posicionamento
de memória a ser utilizada, isto é, qual partição da memória será usada
por um programa a ser executado.
Ao invés de manter o processo alocado na memória principal
durante toda a sua execução, o sistema operacional pode optar
por realizar a troca (swapping). Isso ocorre quando, por exemplo,
o processo não pode mais continuar a sua execução, pois está esperando
a resposta de um dispositivo de E/S, passando o controle
da memória e do processador para outro processo (swap out), que
está aguardando para ser executado. Tendo recebido a resposta da
sua operação de E/S, o sistema operacional faz a troca novamente
dos processos (swap in).
116 Sistemas Operacionais
Figura 6
Exemplo de swapping
Jeffersonsl/Wikimedia Commons
Livro
Para compreender um
pouco mais o conceito e
a gerência de memória
real, bem como a
diferença entre memórias
lógica e física, a distinção
entre partições fixas e
variáveis e swapping,
leia o capítulo 6 da obra
Sistemas operacionais,
e o capítulo 4 da obra
Sistemas operacionais:
projeto e implementação.
OLIVEIRA, R. S de.; CARISSIMI, A
da. S.; TOSCANI, S. S. Porto Alegre:
Bookman, 2010.
A Figura 6 apresenta o swapping entre os processos A, B, C e D, realizado
pelo sistema operacional no uso da memória em determinado
intervalo de tempo.
TANENBAUM, A. S.; WOODHULL,
A. S. 3. ed. Porto Alegre: Bookman,
2008.
4.2 Memória virtual
Vídeo As limitações de espaço e custo da memória real levaram à criação
da memória virtual, dando ao usuário e computador a ilusão de que
existe mais memória do que realmente há. Essa necessidade surgiu
nos sistemas monousuários e foi crescendo conforme os programas
foram crescendo em tamanho e complexidade, resultando em sistemas
multiusuários e seus desafios.
4.2.1 Conceito
Uma solução simples para todos os esforços de organização e gerenciamento
da memória real seria aumentar o tamanho da memória
dentro dos computadores. Porém, como mencionamos anteriormente,
a memória real é um componente caro, e o seu uso em larga escala tornaria
o valor final do computador muito alto e proibitivo para a maioria
dos usuários.
Diante desse impasse, surgiu o conceito de memória virtual, que buscava
solucionar o problema de pouco espaço de memória real, criando
uma ilusão de que existe mais memória do que realmente a máquina
possui. Esse conceito foi empregado pela primeira vez no computador
Memória real e virtual 117
Atlas, desenvolvido pela Universidade de Manchester, na década de
1960.
Figura 7
Evolução da organização da memória
Real Real Virtual
Sistemas
monousuário
dedicados
Sistemas de
multiprogramação
de memória real
Sistemas de
multiprogramação
de memória virtual
Multiprogramação
de partição fixa
Multiprogramação
de partição variável
Paginação
pura
Segmentação
pura
Paginação e
segmentação
combinadas
Absoluta
Realocável
Fonte: Deitel; Deitel; Choffnes, 2005, p. 263.
A Figura 7 mostra como a organização de memória evoluiu dos
sistemas monousuário, com base em memória real, para os sistemas
multiusuários, com base em memória virtual, que fazem uso de
segmentação e paginação.
4.2.2 Organização
O sistema de memória virtual utiliza dois tipos de endereço: os virtuais,
empregados pelos processos, e os físicos ou reais, responsáveis
por informar as localizações físicas de armazenamento na memória
principal.
Quando um processo tenta acessar um endereço virtual, cabe
ao sistema operacional identificar o endereço real correspondente.
Isso é feito por meio de um componente de hardware chamado
unidade de gerenciamento de memória (Memory Management Unit
– MMU).
O processo faz uso de um espaço de endereço virtual (V),
correspondendo a uma faixa de endereços virtuais que um processo
pode referenciar. Em paralelo, o computador usa um espaço de endereço
real (R), que corresponde a um faixa de endereços físicos disponível
no computador. Quando analisamos um sistema de memória
virtual, temos que V > R, isto é, o espaço de endereço virtual é maior
que o espaço de endereço real.
118 Sistemas Operacionais
Figura 8
Armazenamento em dois níveis
Armazenamento
secundário ou auxiliar
ou complementar
Processador (es)
Memória
principal e
caches
Discos
Outros tipos de
armazenamento
secundário
Fonte: Deitel; Deitel; Choffnes, 2005, p. 264.
Conforme ilustrado pela Figura 8, para executar um processo, o sistema
operacional faz uso do armazenamento em dois níveis: os programas
são armazenados em discos ou outros tipos de armazenamento secundário.
Somente quando precisam ser executados pelo processador é
que eles são transferidos para a memória principal e caches.
Figura 9
Mapeamento entre endereços virtuais e endereços reais
Memória virtual
Memória
física
Fonte: Deitel; Deitel; Choffnes, 2005, p. 265.
Mecanismo de
mapeamento de
endereços
Para realizar a tradução dos endereços virtuais em endereços físicos
durante a execução de um processo (Figura 9), o sistema operacional
utiliza mecanismos de tradução dinâmica de endereço (Dynamic
Address Translation – DAT), que seguem a regra de contiguidade artificial.
Isto é, os endereços contíguos do espaço de endereço virtual
Memória real e virtual 119
utilizados por um processo não necessitam ser contíguos no espaço
de endereço real. Os mecanismos de tradução dinâmica de endereços
fazem uso de mapas de tradução de endereços, que são armazenados
em uma tabela de mapas de blocos na memória principal. A diferença
no tamanho dos blocos gera diferentes tipos de organização de memória
virtual, como veremos a seguir.
4.2.2.1 Paginação
1
Tupla é um tipo composto de
dado.
A paginação usa o mapeamento de blocos de tamanho fixo (páginas)
e é representada pela tupla 1 (p, d), em que p corresponde ao
número da página na memória virtual, na qual o item está armazenado,
e d ao deslocamento do início da página p, na qual o item está
armazenado.
Ao realizar a migração da página armazenada na memória secundária
para a memória principal, o sistema operacional faz uso de uma
área para recepcioná-la, área essa que precisa ter o tamanho exato da
página, sendo chamada de moldura da página (page frame – p’), e que
começa em um endereço da memória principal, o qual é um múltiplo
inteiro do tamanho fixo de cada uma das páginas (ps).
Para controlar se uma página virtual (p) corresponde a uma moldura
de página (p’), o sistema operacional faz uso de um registro chamado
de entrada de tabela de páginas (Page Table Entry – PTE), contendo
um bit para indicar se a página está na memória. Caso esteja presente
na memória principal, a PTE armazena o número da moldura da página;
do contrário, a PTE armazena a posição da página na memória secundária.
Essa informação é importante, pois para que o processador
possa acessar a informação de uma página, ela deve estar armazenada
em uma moldura de página na memória principal.
Segundo Deitel, Deitel e Choffnes (2005), a tradução de endereços virtuais
em endereços físicos pode ser realizada das seguintes formas:
a. Mapeamento direto, em que a tradução dinâmica de endereço
na paginação é semelhante à tradução de endereço de bloco.
b. Mapeamento associativo, que armazena a tabela de páginas
em uma tabela associativa, guardando o conteúdo endereçado,
e não a sua localização.
120 Sistemas Operacionais
c. Mapeamento direto/associativo, em que as PTEs são
armazenadas na memória cache associativa, denominada buffer
de tradução lateral (Translation Lookaside Buffer – TLB), que guarda
as páginas que foram referenciadas recentemente, concedendo
melhor desempenho com base no conceito de localidade temporal,
pois, provavelmente, uma página que acabou de ser referenciada
por um processo pode ser referenciada novamente.
d. Tabelas de páginas multiníveis ou tabelas hierárquicas, que
permitem ao sistema operacional armazenar em localizações não
contíguas da memória principal as porções da tabela de páginas
que o processo está utilizando.
e. Tabelas de páginas invertidas, que armazenam uma PTE
na memória para cada moldura de página no sistema. Esse
mecanismo é encontrado em arquiteturas de alto desempenho,
como a Intel IA-64, a HP PA-RISC e a Power PC.
f. Compartilhamento em um sistema de paginação, o qual
diminui o consumo de memória pelos programas que usam
dados/instruções comuns. Podemos citar como exemplo a
chamada do sistema fork do UNIX, que cria um processo-filho
idêntico ao processo-pai, além de compartilhar o endereçamento
virtual entre eles.
Como visto nesta seção, há diversos mecanismos a serem utilizados
pelo sistema operacional para realizar a tradução do endereço de memória
virtual para o seu endereço físico.
4.2.2.2 Segmentação
Uma alternativa para a paginação é a segmentação da memória física,
na qual o programa é dividido em blocos de dados ou instruções,
que são nomeados segmentos, consistindo em localizações contíguas,
porém não precisam ser do mesmo tamanho ou ocupar posições adjacentes
entre si na memória principal. Uma das vantagens dos sistemas
de segmentação virtual é a possibilidade de armazenar na memória
principal somente os segmentos necessários para a execução do processo,
deixando os demais no armazenamento secundário. O endereço de
segmentação virtual é representado pela tupla v = (s, d), em que s corresponde
ao número do segmento na memória virtual e d ao deslocamento
dentro do segmento s, onde está localizado o item referenciado.
Memória real e virtual 121
Para Deitel, Deitel e Choffnes (2005), o sistema operacional faz uso
de três diferentes estratégias para a tradução de endereços de segmentação:
a tradução de endereço de segmentação por mapeamento
direto, na qual o processo faz referência a um endereço de memória
virtual para identificar onde o segmento está armazenado na memória
principal; o compartilhamento em um sistema de segmentação,
em que a sobrecarga do compartilhamento dos segmentos pode ser
menor que o compartilhamento das páginas, pois as estruturas de dados
a serem compartilhadas podem crescer ou diminuir sem alterar
as informações; e a proteção e controle de acesso em sistemas de
segmentação, que busca criar um esquema de implementação de proteção
de memória nos sistemas de segmentação com base nas chaves
de proteção de memória, no qual cada processo está vinculado a um
valor (chave de proteção). Essa última estratégia é implementada na
arquitetura Intel IA-64.
Como visto, há diversos mecanismos a serem utilizados pelo sistema
operacional para realizar a tradução de endereçamento por
segmentação.
4.2.2.3 Sistemas de segmentação/paginação
Os sistemas operacionais da década de 1960, como o MULTICS e
o TSS, combinavam os conceitos de paginação e segmentação. Nessa
abordagem, os segmentos ocupam uma ou mais páginas. Nem todas
as páginas do segmento precisam estar na memória principal simultaneamente,
e as páginas contíguas na memória virtual não necessitam
ser contíguas na memória principal. O endereço da memória virtual é
implementado pela representação v = (s, p, d), em que s corresponde
ao número do segmento; p ao número da página dentro do segmento;
e d ao deslocamento dentro da página que armazena o item.
4.2.3 Gerenciamento
Na seção anterior, abordamos a organização da memória virtual, o
uso de paginação e segmentação e os sistemas que combinam essas
duas técnicas. Nesta seção, analisaremos as possíveis formas de gerenciamento
da memória virtual.
122 Sistemas Operacionais
O conceito de localidade é fundamental para a definição das estratégias
de gerenciamento de memória virtual, apoiada no tempo ou no
espaço. Esse conceito afirma que um processo tende a referenciar a memória
principal seguindo padrões altamente localizados. Trazendo isso
para o mundo computacional, nos sistemas de paginação, os processos
tendem a requisitar certos subconjuntos de páginas com maior assiduidade
(tempo), e essas páginas tendem a ser contíguas entre si (espaço).
Conforme Deitel, Deitel e Choffnes (2005), o gerenciamento de
memória virtual pode fazer uso de diferentes estratégias, como a
estratégia de busca na memória virtual, responsável por definir
quando as páginas ou os segmentos serão movimentados do armazenamento
secundário para a memória principal. Essa técnica pode se
dividir em dois tipos de estratégia: a busca por demanda, que ocorre
quando o sistema operacional fica esperando pela requisição feita pelo
processo para utilizar uma página (Figura 10); e a busca antecipada,
na qual o sistema operacional faz uso de heurísticas para tentar prever
quais páginas ou segmentos serão requisitados pelos processos.
Figura 10
Relação espaço-tempo da política paginação por demanda
Alocação de memória física
Uma
moldura de
página
Processo em
execução
Espera de
página
Espera de
página
Espera de
página
Espera de
página
Espera de
página
Tempo de
“relógio”
F F F F F
F é o tempo médio de uma busca de página
Fonte: Deitel; Deitel; Choffnes, 2005, p. 308.
Memória real e virtual 123
Outra possível estratégia é a estratégia de substituição, em que
o sistema operacional define qual página ou segmento deverá ser
substituído quando a memória principal estiver cheia. Podemos dividir
em oito tipos de estratégia:
1. Substituição aleatória de páginas (Random Page Replacement
– RAND), na qual todas as páginas armazenadas na memória
principal têm a mesma probabilidade de serem selecionadas e
substituídas.
2. Substituição de páginas FIFO (First-In-First-Out), a qual opta por
substituir a página que está há mais tempo no sistema e que,
infelizmente, pode substituir as páginas mais utilizadas pelo
sistema (Figura 11).
Figura 11
Substituição de páginas FIFO
Referência
de página
Resultado
Substituição de
páginas FIFO com
três páginas
A
Falta
A – –
B
Falta
B A –
C
Falta
C B A
A
D
A
Sem falta
Falta
Falta
C B A
D C B
A D C
A é substituída
B é substituída
.
.
Fonte: Deitel; Deitel; Choffnes, 2005, p. 311.
3. Anomalia de Belady ou Anomalia FIFO, baseada nos estudos
do matemático húngaro Laszlo Belady, nos anos 1960, que
descobriu que o aumento do número de molduras de páginas
não reduz o número de falhas – na verdade, aumenta (Figura 12).
124 Sistemas Operacionais
Figura 12
Anomalia de Belady
Referência
de página
Resultado
Substituição de
páginas FIFO com
três páginas disponíveis
Substituição de
páginas FIFO com
quatro páginas disponíveis
A
B
Falta
Falta
A – –
B A –
Falta
Falta
A – – –
B A – –
C
Falta
C B A
Falta
C B A –
D
A
B
E
A
B
C
D
E
Falta
Falta
Falta
Falta
Sem falta
Sem falta
Falta
Falta
Sem falta
D C B
A D C
B A D
E B A
E B A
E B A
C E B
D C E
D C E
Falta
Sem falta
Sem falta
Falta
Falta
Falta
Falta
Falta
Falta
D C B A
D C B A
D C B A
E D C B
A E D C
B A E D
C B A E
D C B A
E D C B
Três “sem falta”
Duas “sem falta”
Fonte: Deitel; Deitel; Choffnes, 2005, p. 312.
4. Substituição da página menos recentemente usada
(Least-Recently-Used – MRU), que faz uso do conceito de
localidade temporal, substituindo a página que ficou mais tempo
armazenada na memória sem ser referenciada (Figura 13).
Figura 13
Substituição de página menos recentemente usada (MRU)
Referência
de página
Resultado
Substituição de
página MRU com três
páginas disponíveis
A
B
C
B
B
A
D
A
B
F
B
Fonte: Deitel; Deitel; Choffnes, 2005, p. 313.
Falta
Falta
Falta
Sem falta
Sem falta
Sem falta
Falta
Sem falta
Sem falta
Falta
Sem falta
A – –
B A –
C B A
B C A
B C A
A B C
D A B
A D B
B A D
F B A
B F A
Memória real e virtual 125
2
Grafos são estruturas matemáticas
representadas pela fórmula
G (V, E), sendo V os vértices
(ou nós) e E (edges - arestas)
os segmentos que ligam dois
vértices.
5. Substituição de página menos frequentemente usada
(Least-Frequently-Used – MFU), a qual decide por substituir a
página que está sendo menos requisitada com base na heurística
de que provavelmente não será requisitada novamente no futuro.
6. Substituição de página não usada recentemente
(Not-Used-Recently – NUR), que se aproxima da MRU, com
pouca sobrecarga, fazendo uso de um bit referenciado ou bit
acessado, o qual indica se a página foi requisitada ou não, e um
bit modificado, o qual indica se a página foi modificada ou não.
7. Substituição de página do tipo relógio, que organiza as páginas
em uma lista circular. O sistema operacional Linux faz uso de
uma variação do algoritmo do relógio.
8. Substituição de página longínqua, que cria um grafo 2 (Figura 14)
de acesso para mapear os padrões de requisição do processo,
substituindo a página não requisitada mais distante no grafo por
uma nova página.
Figura 14
Grafo utilizado pela estratégia de substituição de página longínqua
A
* Indica uma página
referida
B
C
D
E
H
F
G
L
M N O
P
Q é escolhida para
substituição
Q
Fonte: Deitel; Deitel; Choffnes, 2005, p. 317.
Um possível problema para o sistema de memória virtual com paginação
é que, ao requisitar uma página, todas as molduras de página
estão ocupadas naquele momento. Quando isso ocorre, cabe ao sistema,
além de carregar a nova página, decidir qual deverá ser retira-
126 Sistemas Operacionais
da da memória principal para alocar a nova. Desse modo, temos uma
substituição de páginas. Essa estratégia pode ser comparada com a de
substituição de páginas ideal (Theoreticallly Optimal Page Replacement
Algorithm – OPT), a qual busca obter o desempenho ideal substituindo
as páginas que não serão requisitadas futuramente.
4.3 Questões de projeto e implementação
Vídeo
Nas seções anteriores, abordamos possíveis técnicas empregadas
na organização e no gerenciamento da memória real e virtual. Com
base em estudos e análises realizados por projetistas, cientistas e matemáticos,
algumas dessas técnicas são teóricas e ainda não empregadas,
por uma possível limitação de tecnologia ou mesmo por não
serem a melhor solução para o problema.
Nesta seção, mudaremos o nosso foco da teoria para a prática do
projeto, discutindo quais são as preocupações reais dos projetistas
para que os sistemas operacionais consigam organizar e gerenciar os
sistemas de paginação. Depois disso, analisaremos algumas opções de
implementação, isto é, a conversão do projeto em ações reais a serem
executadas pelo sistema operacional no que se refere à memória.
4.3.1 Questões de projeto para sistemas de
paginação
Quando tratamos dos algoritmos de alocação (substituição) de página
temos duas abordagens: a local, que aloca uma porção fixa de
memória para cada um dos processos em execução; e a global, que
considera todos os processos como uma unidade, ignorando as suas
características individuais.
Podemos citar como exemplos de estratégias de substituição de
página global a estratégia MRU global (gMRU), que substitui a página
menos usada recentemente em todo o sistema; e a estratégia
SEQ (sequência), que usa a estratégia MRU para substituir as páginas
até que uma sequência de falta de página seja detectada. Quando isso
ocorre, o sistema passa a utilizar a estratégia de substituição da página
usada mais recentemente (UMR).
Memória real e virtual 127
Para medir se o gerenciamento de memória virtual está sendo
executado de modo eficiente, o sistema operacional faz uso da
taxa de falta de página. O algoritmo de frequência de falta de
página (Page-Fault-Frequency – PFF) realiza o ajuste do conjunto de
páginas residente do processo, isto é, as páginas do processo que
estão alocadas em memória, com base na frequência com que esse
processo acusa a falta de página ou no tempo entre as faltas de
página, chamado de tempo entre faltas do processo. Uma vantagem
desse algoritmo é que ele ajusta o conjunto de páginas residente
de um processo de maneira dinâmica, de acordo com a mudança
no comportamento do processo.
A teoria do conjunto de trabalho para o comportamento
do programa, proposta pelo cientista da computação
Peter J. Denning, afirma que para um programa ser executado de
modo eficaz o sistema deve manter na memória principal apenas
as páginas que fazem parte do conjunto de trabalho corrente do
processo. Caso isso não aconteça, o sistema pode armazenar páginas
desnecessárias (thrashing), comprometendo a utilização do
processador. A principal meta do gerenciamento de memória do
conjunto de trabalho é reduzir a alocação incorreta de memória.
Quando não são mais solicitadas por um processo, as páginas
devem ser retiradas de seu conjunto de trabalho. Porém, as inativas
podem permanecer na memória principal durante um longo
período, até que sejam detectadas pela estratégia de gerenciamento
de memória utilizada pelo sistema operacional. Uma possível
solução para esse problema seria o processo emitir um comando
de liberação voluntária da página, informando ao sistema que esta
não é mais necessária.
Alguns sistemas melhoram o desempenho e a utilização de memória
fazendo uso de diferentes tamanhos de páginas. Segundo
Deitel, Deitel e Choffnes (2005), os projetistas de sistema operacional
podem optar por três diferentes tamanhos de página:
128 Sistemas Operacionais
O tamanho de
página pequeno,
que reduz a
fragmentação interna
e permite a redução
da quantidade de
memória necessária
para conter o
conjunto de trabalho
de um processo.
O tamanho de
página grande, que
reduz o desperdício de
memória provocado
pela fragmentação
de tabela e permite à
entrada da TLB mapear
uma região maior da
memória, melhorando
o desempenho.
Os tamanhos
diferentes de
página, que criam
a possibilidade
de fragmentação
externa.
Vyacheslavikus/ Shutterstock
Segundo Tanenbaum e Bos (2015), a maioria dos computadores
possui um único espaço para endereçamento de programas e dados,
conforme Figura 15. Caso o espaço seja grande o suficiente, tudo ocorrerá
bem; do contrário, os projetistas e desenvolvedores terão de se esforçar
para acomodar os programas e dados em um espaço insuficiente.
Figura 15
Espaço de endereçamento único (a) – Espaço de Programas (I) e Dados (D) separados
Espaço de
endereçamento único
Espaço I Espaço D
2 32 2 32
Página não utilizada
Dados
Dados
Programa
Programa
0
(a)
0
(b)
Fonte: Tanenbaum e Bos, 2015, p. 136.
Uma forma de compartilhamento de recursos pode ser feita pelo
compartilhamento de bibliotecas, as Dynamic-link Library (DLLs) – bibliotecas
de ligação dinâmica –, utilizadas no sistema operacional
Windows, desenvolvido pela Microsoft. Quando um programa multiusuário
é executado, ao invés de carregar mais de uma vez os seus
recursos em memória, se ele faz uso de bibliotecas compartilhadas,
estas são alocadas somente uma única vez.
Memória real e virtual 129
4.3.2 Questões de implementação
Conforme Tanenbaum e Bos (2015), existem quatro situações em
que o sistema operacional precisa se envolver com a paginação:
A
B
Na criação do processo, quando o sistema operacional precisa determinar
o tamanho inicial do programa e realizar a criação da tabela
de páginas a ser usada por ele.
No tempo de execução do processo, quando a MMU deve ser reinicializada
e a TLB limpa os registros do processo anterior.
C
D
Na ocorrência da falta de página, quando o sistema operacional realiza
a leitura dos registradores (hardware) para identificar qual endereço
virtual está gerando a falta de página, corrigindo o erro por meio do descarte
de uma página que não está sendo utilizada e alocando uma nova
página a ser usada pelo processo que deu erro.
Na finalização do processo, quando o sistema operacional libera
a tabela de páginas, as páginas e o espaço em disco ocupado pelas
páginas.
Quando um processo requisita uma página que não está na memória
principal, a instrução responsável pela falta de página sofre um
bloqueio em sua execução. Isso gera uma interrupção, que é encaminhada
para o sistema operacional, ficando este responsável por pesquisar
no disco rígido a página solicitada, carregando-a na memória e
reiniciando a instrução.
O kernel (núcleo) Mach, desenvolvido pela Carnegie Mellon
University, na década de 1980, serviu como base para o GNU Hurd,
núcleo desenvolvido pelo projeto GNU, e o XNU kernel, utilizado nos
sistemas operacionais dos computadores e dispositivos da Apple –
macOS, iOS e watchOS.
O Mach foi pioneiro, pois nele os gerenciadores de memória
passaram a ser executados no modo usuário (Figura 16). O processo
do usuário faz a requisição de uma página. Ao descobrir que esta
não está disponível na memória, o sistema operacional registra a
sua falta, que é recebida pelo manipulador de faltas, responsável
por informar ao paginador externo, executado no espaço do usuá-
130 Sistemas Operacionais
rio, sobre a necessidade da página. O paginador externo solicita
a página ao disco (armazenamento secundário) que, ao recebê-la,
devolve-a ao manipulador de faltas. Este a entrega ao manipulador
de MMU, que gera o mapa da página necessário para a continuidade
da execução do processo.
Figura 16
Tratamento de falta de página no espaço do usuário
Memória principal
3. Solicitação de página
Disco
Espaço do
usuário
Processo
do usuário
2. Página
necessária
Paginador
externo
4. Página
chega
Espaço do
núcleo
1. Falta
de página
Fonte: Tanenbaum e Bos, 2015, p. 144.
Manipulador
de faltas
5. Aqui está a
página
6. Mapa
da página
Manipulador
de MMU
A vantagem dessa abordagem está na modularidade e flexibilidade
que são concedidas ao código. No entanto, a principal desvantagem reside
na sobrecarga criada pela comunicação entre o núcleo e o usuário,
em virtude da necessidade de troca de mensagens entre as partes para
executar o fluxo descrito.
Livro
Para compreender um
pouco mais a implementação
da memória virtual
e a alocação de memória,
leia a seção 4.3 da obra
Sistemas operacionais: projeto
e implementação.
TANENBAUM, A. S.; WOODHULL,
A. S. 3. ed. Porto Alegre: Bookman,
2008.
CONSIDERAÇÕES FINAIS
Neste capítulo, aprofundamos a nossa visão sobre a memória do
computador, seja ela real ou virtual. Cada vez que um usuário solicita a
execução de um programa, o sistema operacional deve selecionar quais
são as páginas necessárias para que o programa seja executado. Elas deverão
ser armazenadas na memória principal, onde estarão disponíveis
para serem utilizadas pelo processador. Caso não haja memória suficiente,
este pode fazer uso da memória virtual para não impedir o processo.
Tudo é feito antes da execução, em um sincronismo e uma velocidade
imperceptíveis ao usuário. Esse fluxo se baseia em algoritmos e estudos
feitos pelos projetistas de hardware/software, cientistas da computação e
matemáticos, que buscam sempre identificar possíveis problemas e definir
novas formas de projeto e implementação.
Memória real e virtual 131
Como estamos diante de uma constante evolução do hardware, acompanhada
pela disseminação no uso do software – que se torna cada vez
mais complexo e abrangente –, não seria surpresa se novas tecnologias
surgissem e substituíssem os conceitos que até esse momento são considerados
como verdades absolutas.
ATIVIDADES
1. O que determina a estratégia de busca?
2. O que determina a estratégia de posicionamento?
3. O que determina a estratégia de substituição?
4. Qual a diferença entre os endereços virtuais e os endereços físicos?
5. Qual o papel da MMU?
REFERÊNCIAS
DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. Sistemas operacionais. São Paulo: Pearson
Universidades, 2005.
TANENBAUM, A. S.; BOS, H. Sistemas Operacionais Modernos. São Paulo: Pearson
Universidades, 2015.
132 Sistemas Operacionais
5
Segurança em sistemas
operacionais
Ao falarmos de segurança em sistemas operacionais, focamos
as medidas tomadas para evitar o acesso não autorizado ao sistema,
aos seus recursos e às informações sensíveis armazenadas no
computador. Além dessas questões, o sistema deve ser flexível e
resiliente contra as tentativas de invasão e incapacitação do computador,
fazendo uso de mecanismos para proteger o hardware e
os seus serviços de possíveis invasores.
Neste capítulo, abordaremos os seguintes assuntos: a criptografia
e formas de se garantir que a mensagem consiga ser interpretada
somente pelo destinatário correto; a autenticação, o meio de
identificar se o usuário realmente é quem ele diz ser; o controle de
acesso, o modo que garante que o usuário tenha somente acesso
às funcionalidades que são destinadas a ele; os ataques à segurança
do computador, da rede de computadores ou dos sistemas operacionais;
a prevenção de ataques e soluções de segurança, as ações
possíveis para responder ou se proteger dos ataques; e a comunicação
e protocolos de segurança, que analisam as vulnerabilidades
da comunicação entre computadores, bem como os protocolos
implementados para garantir a segurança dessas comunicações.
5.1 Criptografia
Vídeo De acordo com Deitel, Deitel e Choffnes (2005), a criptografia trata
da codificação e decodificação de dados, de modo que esses possam
ser interpretados apenas pelos receptores a que se destinam.
Isso ocorre devido à transformação dos dados por meio de uma cifra
Segurança em sistemas operacionais 133
Cifra ou sistema criptográfico é
um algoritmo matemático para a
criptografia das mensagens.
1 ou sistema criptográfico 1
, que realiza a criptografia dos dados (texto
comum) em um texto cifrado, fazendo uso de uma chave como
entrada. Ao utilizar uma chave diferente, a cifra gerará um texto
cifrado diferente. Essa ação evita que receptores indesejados, que
não possuem uma chave para decriptação, consigam transformar o
texto cifrado em um texto comum novamente.
2
Caio Júlio César foi um líder militar
e político romano responsável
pela transformação da República
romana em um Império.
Segundo Deitel, Deitel e Choffnes (2005), os dois principais tipos
de cifras utilizadas na Antiguidade eram a cifra de substituição,
que, ao encontrar uma letra no texto comum, era substituída
por outra. Devido à sua criação ser atribuída a Júlio César 2
, essa
modalidade também é conhecida como cifra de César; e a cifra de
transposição, na qual a ordem das letras é alterada. Chamados de
algoritmos restritos, a desvantagem no uso dessas estratégias reside
na necessidade de o emissor e o receptor da mensagem se
lembrarem do algoritmo utilizado, além de mantê-lo em segredo, o
que se torna impraticável quando isso abrange um grande número
de pessoas.
Os sistemas criptográficos modernos usam algoritmos que
atuam nos bits ou grupos de bits (blocos) dos dados, e não nas
letras, como os algoritmos antigos. As chaves, utilizadas para a
criptografia e decriptação, são cadeias binárias com uma chave de
tamanho determinado. Por exemplo, um sistema criptográfico de
64 bits usa uma chave de 64 bits. Ao analisarmos o tamanho da
chave utilizada, podemos afirmar que quanto maior a chave, maiores
serão o tempo e a capacidade computacional necessários para
desvendar (quebrar) a cifra. Também será menor o desempenho
do sistema, pois o tempo de criptografia e de decriptação serão
maiores do que ao utilizar uma chave menor.
A criptografia por chave secreta, ou criptografia simétrica, é um
exemplo de sistema criptográfico moderno, que utiliza a mesma
chave secreta tanto para criptografar quanto decriptar um texto.
Nesse sistema, o emissor criptografa a mensagem fazendo uso de
uma chave secreta, enviando a mensagem criptografada ao receptor,
que usa a mesma chave secreta para decriptar a mensagem
recebida (Figura 1).
134 Sistemas Operacionais
Figura 1
Fluxo de uma mensagem fazendo uso de chave secreta
Compre 100 ações
da empresa X
Criptografa
XY%#?42%Y
Meio de
comunicação
(como internet)
Emissor
Texto comum
Chave
simétrica
secreta
Texto cifrado
Mesma chave
simétrica secreta
Compre 100
ações da
empresa X
Decripta
Texto comum
Receptor
Fonte: Deitel; Deitel; Choffnes, 2005, p. 564.
A limitação desse sistema reside na necessidade de o emissor e o
receptor encontrarem uma forma segura de compartilhar a chave secreta
utilizada. Uma possível solução é fazer uso de uma central de distribuição
de chaves (Key Distribution Center – KDC), que gera uma chave
de sessão utilizada pelo emissor e o receptor durante uma transação
(Figura 2).
Figura 2
Uso de uma central de distribuição de chaves
1
Emissor
“Quero me
comunicar com
o receptor”
Central de distribuição
de chaves (KCD)
Receptor
2
3
Chave de sessão
criptografada com a
chave KDC do emissor
Fonte: Deitel; Deitel; Choffnes, 2005, p. 564.
Criptografa
Chave de sessão (chave
secreta simétrica)
Criptografa
3
Chave de sessão
criptografada com a
chave KDC do receptor
Segurança em sistemas operacionais 135
Podemos citar como exemplos de algoritmos de criptografia simétrica:
o padrão para criptografia de dados (Data Encryption Standard
– DES), desenvolvido na década de 1970 pela IBM e utilizado pelo governo
norte-americano e pelo Instituto Nacional Americano de Padrões
(American National Standards Institute – ANSI) até o final da década de
1990, quando, então, não foi mais considerado seguro; a partir daí, foi
substituído pelo Triple DES ou 3DES, que aplicava o padrão DES por
três vezes em cada um dos blocos de dados, utilizando chaves diferentes.
O resultado foi considerado seguro, porém, em virtude das três
passagens do DES, a sua execução aumentava a sobrecarga da criptografia,
reduzindo o desempenho da operação. Em 2000, foi substituído
pelo Padrão Avançado de Criptografia (Advanced Encryption Standard
– AES), que utiliza chaves e blocos de 128, 192 e 256 bits.
A criptografia por chave pública também é um exemplo de sistema
criptográfico moderno. Foi desenvolvida na década de 1970 por dois
pesquisadores da Universidade de Stanford, Whitfield Diffie e Martin
Hellman, que buscavam uma solução para a necessidade de compartilhamento
das chaves simétricas. Esse sistema usa duas chaves: uma
pública – distribuída livremente e utilizada para cifrar a mensagem; e
outra privada, que é mantida em segredo pelo seu proprietário e é utilizada
para decifrar a mensagem (Figura 3).
Figura 3
Fluxo de uma mensagem fazendo uso de chave pública
Compre 100 ações da
empresa X
Criptografa
XY%#?42%Y
Meio de comunicação
(como internet)
Emissor
Texto comum
Chave pública
do receptor
Texto cifrado
Chave privada
do receptor
Compre 100 ações da
empresa X
Criptografa
Receptor
Texto comum
Fonte: Deitel; Deitel; Choffnes, 2005, p. 566.
Os algoritmos de chave pública são denominados funções de uma
via ou armadilha, pois a ação de cifrar uma mensagem utilizando uma
136 Sistemas Operacionais
chave pública não requer muitos recursos computacionais. Entretanto,
a sua decriptação, sem ter acesso à chave privada, necessita de tempo
e de recursos computacionais elevados.
São exemplos de algoritmos de criptografia por chave pública: o algoritmo
Rivest-Shamir-Adleman (RSA), utilizado amplamente na internet
em navegadores Web, servidores e sistemas de e-mail, foi desenvolvido
por Ron Rivest, Adi Shamir e Leonard Adleman, pesquisadores do
MIT na década de 1970; e o algoritmo Privacidade Razoável (Pretty
Good Privacy – PGP), desenvolvido em 1991 pelo pesquisador Philip
Zimmermann, utilizado na criptografia de mensagens e arquivos de
e-mail, confirmando a identidade do emissor ou do conteúdo enviado.
Uma forma de assinar mensagens de e-mail e outros documentos
digitais para garantir a identidade do emissor é o uso de assinaturas
digitais. A assinatura digital submete o documento a uma função de
resumo de sentido único, que produz um resultado, chamado resumo
(hash), que possui um tamanho fixo, independentemente do tamanho
do documento original. Como exemplos de função de resumo de sentido
único temos: o compêndio de mensagens 5 (Message Digest 5 –
MD5), que gera um hash de 16 bytes; e o algoritmo hash seguro (Secure
Hash Algorithm – SHA-1), que gera um hash de 20 bytes. Ao obter o
resumo, o proprietário do documento usa uma chave privada sobre
ele, gerando um bloco de assinatura, que é anexado ao documento
enviado para o receptor (Figura 4). Quando o documento é recebido, o
receptor realiza a decriptação do resumo, via MD5 ou SHA-1. Ao mesmo
tempo, ele realiza a decriptação do bloco de assinatura, fazendo
uso de uma chave pública. Caso o valor do resumo decriptado não seja
igual ao valor do bloco de assinatura decriptado, o documento é considerado
adulterado.
Figura 4
(a) Cálculo de um bloco de assinatura. (b) Documento recebido pelo receptor
Documento
original
Documento
reduzido a um
valor resumo
Resumo
Valor resumo
submetido à D
D(resumo)
Documento
original
Fonte: Tanenbaum; Bos, 2015, p. 384.
(a)
Bloco de
assinatura
{
D(resumo)
(b)
Segurança em sistemas operacionais 137
Vídeos
Para você compreender mais a
criptografia e suas aplicações na
segurança de dados, recomendamos
os vídeos Entendendo
conceitos básicos de criptografia
(parte 1 e 2), publicados no
canal Fábio Akita.
Parte 1. Disponível em:
https://www.youtube.com/
watch?v=CcU5Kc_FN_4.
Acesso em: 7 ago. 2020.
Parte 2. Disponível em:
https://www.youtube.com/
watch?v=HCHqtpipwu4. Acesso
em: 7 ago. 2020.
Nos anos 2000, o governo dos EUA aprovou o algoritmo de assinatura
digital (Digital Signature Algorithm – DSA) que concedeu à assinatura
digital a mesma validade judicial de uma assinatura por escrito.
Uma forma de compartilhar a chave pública com o receptor é
anexar um certificado à mensagem, com o nome do usuário e a
chave pública, que é fornecida por um terceiro confiável. Nomeamos
de autoridade certificadora (AC) a empresa que realiza a validação
dos certificados. Para que um receptor possa realizar a
decriptação de um certificado, ele precisa da chave pública da AC
fornecida por uma infraestrutura de chave pública, ou carregada
previamente, como no caso dos navegadores Web.
5.2 Autenticação
Vídeo Uma das grandes preocupações do sistema operacional no que
se refere à segurança é identificar os usuários que o estão acessando,
além de definir o nível de permissão de acesso que cada usuário
possui. Conforme Tanenbaum e Bos (2015), a maioria dos métodos de
autenticação de usuários tem como base um dos três princípios gerais
da identificação:
A
B
Alguma coisa que o usuário sabe, como uma senha, um número de
identificação pessoal (Personal Identification Number – PIN) etc.
Alguma coisa que o usuário tenha em posse, por exemplo, um crachá,
uma carteira de identidade, uma chave, e assim por diante.
Glossário
hacker: pessoa que busca
conhecer e/ou modificar os
aspectos mais internos de
dispositivos, programas e redes
de computadores.
cracker: indivíduo que pratica
a quebra (ou cracking) de um
sistema de segurança de modo
ilegal.
C
Alguma coisa que o usuário é, ou seja, uma característica exclusiva
dele – impressão digital, varredura de retina, assinatura, entre outras.
Para se garantir uma segurança adicional, o sistema pode fazer uso
de dois desses princípios.
Antes de causar algum problema, cabe ao invasor obter acesso ao
sistema, passando pelo procedimento de autenticação. Erroneamente
conhecidos como hackers, as pessoas que tentam invadir sistemas
computacionais sem a devida autorização são nomeados crackers.
138 Sistemas Operacionais
A proteção por senha é considerada o esquema de autenticação
mais comum, no qual o usuário define e memoriza uma senha que é
fornecida ao sistema, para que ele possa acessar o sistema ou um aplicativo.
Uma das desvantagens dessa estratégia se fundamenta no fato
de que os usuários, comumente, definem senhas de fácil memorização,
usando informações pessoais, como nome do próprio usuário ou
de um membro da família, nome do animal de estimação, data de aniversário,
endereço residencial, livro ou filme favorito etc. O problema
disso é que alguém mal-intencionado, de posse dessas informações,
pode tentar acessar o sistema várias vezes (quebra por força bruta),
fazendo uso das várias senhas possíveis, até conseguir o acesso. Para
evitar a quebra por força bruta, os sistemas passaram a limitar o número
de tentativas de aceso a serem realizadas em um terminal por
determinado usuário.
O UNIX utiliza criptografia para armazenar suas senhas. Quando o
usuário digita a senha, ela é criptografada e comparada com a senha
armazenada no arquivo de senhas. Além disso, o UNIX possui o envelhecimento
de senha (password aging), que permite ao administrador
definir o período de validade das senhas, que deverá ser redefinida
pelo usuário quando expirar.
Outra forma de tornar um sistema seguro é fazer uso da biometria, na
qual o usuário é identificado por uma informação pessoal exclusiva, como
a impressão digital, uma varredura da retina ou íris etc. A Microsoft incluiu
a opção de autenticação por biometria com o Windows 2000 e Windows
XP, fazendo uso da Interface para Programação de Aplicação Biométrica
(Biometric Application Programming Interface – BAPI).
Também podemos citar o uso dos cartões inteligentes (smart cards)
(Figura 5). Parecidos com os cartões de crédito, eles podem ser utilizados
para a autenticação do usuário ou para armazenar dados – chaves
privadas, certificados digitais etc.
Figura 5
Uso de um cartão inteligente (smart card) para autenticação
Cartão
inteligente
1. Desafio enviado ao
cartão inteligente
Computador
remoto
2. Cartão
inteligente calcula
a resposta
Fonte: Tanenbaum; Bos, 2015, p. 404.
Leitor de cartão
inteligente
3. A resposta
é devolvida
Segurança em sistemas operacionais 139
Buscando melhorar a autenticação do usuário, alguns sistemas aplicam
a autenticação de dois fatores – usam dois meios para identificar
o usuário, no qual ele utiliza inicialmente a biometria ou o cartão inteligente,
acompanhado de uma senha.
As preocupações com segurança não se resumem somente à identificação
dos usuários. Conforme Deitel, Deitel e Choffnes (2005), estima-se
que 70% a 90% dos ataques a redes corporativas é realizado internamente
– usuários da própria empresa (funcionários ou terceiros), que devidamente
logados roubam ou compartilham informações sigilosas e valiosas
da empresa. Podemos citar como formas de ataques internos:
a. As bombas lógicas: códigos inseridos no sistema operacional
de produção da empresa e que dependem da inserção diária de
uma senha para que nada ocorra. Caso o autor da bomba lógica
seja demitido, a bomba lógica não vai mais ser alimentada com
uma senha e acabará “explodindo”.
b. Os alçapões (trap door): códigos inseridos por um programador
para evitar uma verificação, por exemplo, acessando o sistema
com o login 12345, sem a necessidade de informar uma senha.
Isso pode ser evitado com a realização de revisões de código
constantes.
c. O logro na autenticação do usuário: tela criada por um
desenvolvedor muito parecida com a tela de autenticação original
(Figura 6), que é executada nos computadores de uma rede,
normalmente em redes de computadores públicos, utilizadas em
universidades e colégios. Ao fazer uso da tela de autenticação
falsa, o programador coleta os dados de autenticação dos
usuários. A única forma de se evitar o logro na autenticação é
combinar teclas ao processo de autenticação, como o que é feito
no Windows, que solicita ao usuário apertar as teclas Ctrl + Alt + Del
para exibir a tela de autenticação, desconectando o usuário que
estava logado previamente naquele computador, encerrando,
assim, qualquer execução prévia.
Figura 6
(a) Tela correta de autenticação. (b) Tela de autenticação adulterada
Usuário:
Usuário:
Fonte: Tanenbaum; Bos, 2015, p. 407.
(a)
(b)
140 Sistemas Operacionais
Para tentar evitar essa ameaça dos ataques internos à segurança,
o MIT desenvolveu um protocolo de código-fonte aberto, denominado
Kerberos, que usa criptografia de chave secreta, utilizado na autenticação
dos usuários ou para manter a privacidade da comunicação e
integridade dos dados de uma rede.
O Kerberos utiliza um servidor de autenticação e um serviço de
concessão de bilhetes (Ticket Granting Service – TGS), que seguem
o seguinte fluxo:
O usuário
fornece login
e senha para
o servidor de
autenticação.
Caso os dados
fornecidos sejam
válidos, o servidor
de autenticação
emite um bilhete
de concessão de
entrada (Ticket-
-Granting Ticket
– TGT), que é
criptografado
fazendo uso da chave
secreta fornecida
pelo usuário.
O usuário envia o
TGT decriptado ao
TGS e solicita um
bilhete de serviço,
que autorizará ao
usuário o acesso
aos serviços da
rede.
Se o TGT for
válido, o TGS vai
gerar um bilhete
de serviço que
é criptografado
fazendo uso da
chave secreta do
usuário.
Ao receber o
bilhete de serviço,
o usuário o
decripta e o utiliza
para acessar os
recursos da rede.
Para evitar o uso indiscriminado do bilhete de serviço, ele possui um
prazo de expiração, que pode ser renovado ou não pelo TGS.
Em busca de simplificar o processo de autenticação, foram criados
os sistemas de assinatura única, que permitem ao usuário acessar o
sistema somente uma vez, utilizando uma única senha, que permite
o acesso a várias aplicações do sistema em diferentes computadores.
Exemplos de assinatura única:
a. Scripts de acesso de estações de trabalho: enviam a senha do
usuário aos servidores de aplicação, autenticando-o e permitindo
o seu acesso futuro.
b. Scripts de servidor de autenticação: realizam a autenticação
dos usuários fazendo uso de um servidor responsável por
gerenciar as conexões dos usuários e das aplicações acessadas
por eles. O seu uso é considerado mais seguro do que os scripts
de acesso de estações de trabalho, pois a senha é armazenada
em um servidor, e não na estação do cliente.
Segurança em sistemas operacionais 141
Vídeo
Para que você se
aprofunde no conceito
de autenticação, sua
necessidade e práticas,
recomendamos o vídeo
Ciclo de palestras Segurança
da Internet - CERT.
br: Autenticação, do canal
NIC.br. O vídeo faz parte
do ciclo de palestras
focadas em segurança da
internet.
Disponível em: https://
www.youtube.com/
watch?v=5QZRsH7vg5g. Acesso
em: 6 ago. 2020.
c. Autenticação por ficha (token): gerada quando o usuário é
autenticado, habilitando-o a acessar as aplicações desejadas.
Com o intuito de garantir a segurança do sistema que gera o
token, ele é protegido com o uso de criptografia ou senha única.
Para implementar essa autenticação, as aplicações devem ser
adaptadas a fim de usarem tokens como acesso.
Entre as empresas que desempenharam um papel mais ativo
no uso de assinatura única, podemos destacar: a Liberty Alliance
Project, uma organização fundada em 2001 para estabelecer
padrões, protocolos e melhores práticas para autenticação em
sistemas computacionais; a Microsoft, que utiliza o Windows Live
ID para que os usuários acessem os seus aplicativos; e a Novell,
empresa desenvolvedora do sistema operacional de rede Novell
NetWare, que fazia uso do SecureLogin.
5.3 Controle de acesso
Vídeo Cabe ao sistema operacional proteger o computador contra o uso
indevido e mal-intencionado dos recursos computacionais, protegendo
os seus serviços e suas informações de usuários ou softwares que
tenham conseguido acessá-lo. Isso é feito pelos direitos de acesso –
que protegem os recursos e serviços do computador contra a ação
de usuários que podem representar algum risco para o sistema –, com
restrição ou limitação das ações a serem executadas nos recursos. Os
direitos de acesso são gerenciados por listas de controle de acesso ou
por listas de capacidades (DEITEL; DEITEL; CHOFFNES, 2005).
A forma encontrada pelo sistema operacional para manter a segurança
é gerenciar o acesso aos dados e aos recursos internos. Isso é
feito por meio de direito de acesso, que permite a inúmeros sujeitos
(usuários, processos, programas etc.) acessarem vários objetos (discos,
processadores, memória principal, processos, serviços, entre outros).
O sistema operacional define a forma com que o usuário acessa o objeto
pelo privilégio de acesso que é concedido a ele, que pode ser de
leitura, escrita, execução, impressão etc. Os direitos de acesso podem
ser: copiados, isto é, conceder o direito de acesso de um usuário para
outro; transferidos, o direito de acesso de um usuário é entregue para
outro usuário; ou propagados, há a possibilidade de um usuário copiar
o seu direito de acesso para vários usuários.
142 Sistemas Operacionais
Cabe ao sistema operacional proteger os objetos da ação dos sujeitos
que podem de maneira inadvertida ou mal-intencionada colocar em risco a
segurança do sistema operacional ou encerrar a execução das aplicações.
Uma coleção de direitos de acesso é chamada de domínio de proteção,
sendo representada por um par ordenado, contendo o nome do
objeto e seus privilégios. Por exemplo, se um usuário possui permissão
de leitura e escrita sobre o arquivo exemplo.txt, o seu domínio de proteção
será <exemplo.txt, {read, write}>.
De acordo com Deitel, Deitel e Choffnes (2005), o controle de acesso
pode ser dividido em três níveis conceituais:
A
B
C
Modelo de segurança: define os sujeitos, objetos e privilégios de um
sistema operacional.
Política de segurança: define para os usuários quais são os privilégios
que eles possuem. A política de segurança é definida pelo usuário
ou administrador do sistema operacional.
Mecanismo de segurança: forma com que o sistema operacional realiza
a implementação da política de segurança adotada por ele.
Ao analisar as políticas de segurança, em sua maioria, os sistemas
operacionais optam pelo princípio do mínimo privilégio, no qual o
usuário recebe permissão de acesso somente nos objetos necessários
para a execução das suas atividades; o UNIX e o Linux utilizam o
modelo de controle de acesso discricionário (Discretionary Access
Control – DAC), que concede controle das permissões de um objeto
ao seu criador. Já os sistemas governamentais, que processam dados
sigilosos, usam o controle de acesso obrigatório (Mandatory Access
Control – MAC), em que um esquema de permissão central é utilizado
para gerenciar os sujeitos e os objetos.
3
Ao examinar os mecanismos de segurança, ou seja, as formas com
que o sistema operacional implementa a sua política de segurança, o
Matriz é uma tabela organizada
em linhas e colunas no formato
sistema operacional pode fazer uso das seguintes estratégias:
m x n, em que m representa o
a. Matrizes de controle de acesso: utilizam uma matriz 3 número de linhas (horizontal), e
para
n o número de colunas (vertical).
armazenar a relação dos sujeitos, armazenados nas linhas; e dos
objetos, armazenados nas colunas. Ao adotar essa estratégia, o
Segurança em sistemas operacionais 143
sistema operacional usa o princípio do mínimo privilégio nos
direitos de acesso. Isso é feito para impedir que um usuário
acesse um objeto, caso não esteja devidamente descrito na
matriz. Como vantagem desse modelo, podemos destacar a
simplicidade. Como desvantagem, quando os sistemas são
muito complexos, a matriz pode ficar muito grande e com vários
espaços vazios (Figura 7).
Figura 7
Matriz de controle de acesso
Objeto
Domínio Arquivo1 Arquivo2 Arquivo3 Arquivo4 Arquivo5 Arquivo6 Impressora1 Plotter2
1 Leitura
Leitura
Escrita
2 Leitura
Leitura
Escrita
Execução
Leitura
Escrita
Escrita
3
Leitura
Escrita
Execução
Escrita
Escrita
Fonte: Tanenbaum; Bos, 2015, p. 386.
b. Listas de controle de acesso: usam listas para armazenar os
direitos de acesso. Essa estratégia pode ser implementada tanto
para os sujeitos quanto para os objetos. Ao optar pelo uso das
listas de controle de acesso, o sistema operacional também
usa o princípio do mínimo privilégio. A vantagem desse modelo
é não encontrarmos os espaços vazios, que podem ocorrer no
armazenamento em matriz. Podemos citar como desvantagem a
dificuldade de consultar várias listas para identificar os usuários
que possuem direito de acesso à determinada aplicação.
c. Listas de capacidades: armazenam as capacidades, isto é,
ponteiros ou fichas que concedem os privilégios aos sujeitos
(Figura 8). Elas não podem ser modificadas, mas podem ser
reproduzidas. A capacidade está vinculada a um objeto, sendo
criada com ele. Quando a implementação da capacidade utiliza
ponteiros, ela armazena o seu endereço na memória principal,
o que acelera o acesso ao objeto. A desvantagem dessa forma
de implementação é que, caso o objeto mude de endereço,
o seu ponteiro também deverá ser modificado. Quando a
implementação utiliza fichas, ele usa um mecanismo de hash
para criar uma sequência exclusiva de bits. Como desvantagem
144 Sistemas Operacionais
no uso de listas de capacidades, podemos citar o problema do
“objeto perdido”, que ocorre quando a última capacidade de um
objeto é destruída, impedindo que o objeto seja acessado depois
disso. A solução para esse problema é fazer com que o sistema
operacional mantenha pelo menos uma capacidade por objeto.
Cabe ao sistema operacional controlar a propagação e monitorar
as capacidades. Uma vantagem desse modelo ocorre quando a
implementação da capacidade utiliza ponteiros, ela armazena o
seu endereço na memória principal, o que acelera o acesso ao
objeto.
Figura 8
Lista de capacidades
Processo
A
Processo
B
C
Espaço do
usuário
F1
F2
F3
F1:R
F2:R
Fonte: Tanenbaum; Bos, 2015, p. 389.
F1:R
F2:RW
F3:RWX
F2:R
F3:RX
C-list
Espaço
do núcleo
No Linux, cada um dos arquivos do sistema recebe atributos de controle
de acesso que vão definir as permissões de segurança do arquivo,
ou seja, uma combinação das permissões de leitura (read – r), escrita
(write – w) e execução (execute – x) que é atribuída a três níveis diferentes:
o do usuário, em que as permissões são concedidas ao dono
do arquivo; o de grupo, que
concede as permissões a um
membro de um grupo; e, por
fim, o nível outros, em que as
permissões são atribuídas a
um usuário que não é o dono
do arquivo nem membro de
um grupo.
A Figura 9 mostra a sequência
de controle de acesso
para os diretórios, links
Vídeo
Para entender o controle
de acesso e seu papel na
segurança dos recursos
do sistema operacional,
assista ao vídeo Autenticação
ou autorização?,
publicado pelo canal
DevPleno.
Disponível em: https://
www.youtube.com/
watch?v=acGpu4z0azk. Acesso em:
3 ago. 2020.
Figura 9
Atributos de controle de
acesso no Linux
Segurança em sistemas operacionais 145
Vídeo
(caminhos simplificados para diretórios) e arquivos no Linux composta
das letras r, w e x, que vão indicar os privilégios de leitura (read), escrita
(write) e execução (execute), respectivamente, atribuídos a eles.
5.4 Ataques à segurança
De tempos em tempos, recebemos notícias relatando ataques cibernéticos
a corporações e empresas de comércio eletrônico. Fazendo
uso de ataques de recusa de serviço (Denial-of-Service – DoS), vírus e
vermes (worms), esses invasores podem levar à perda de bilhões de
dólares roubando dados alheios. Nesta seção, vamos abordar possíveis
formas de ataque aos sistemas operacionais.
Quando é realizado um ataque criptoanalítico, os invasores tentam
decriptar um texto previamente cifrado sem possuir a chave para a decriptação.
O objetivo desse tipo de ataque é descobrir a chave utilizada
por meio do texto cifrado. O gerenciamento das chaves e das suas datas
de expiração pode servir como forma de diminuir os ataques, pois, quanto
maior o tempo de uso de uma chave, maior será o número de textos
gerados que poderão ser utilizados para poder identificá-la.
Vírus é um código executável, normalmente anexado a uma mensagem
de e-mail ou oculto em um arquivo (áudio de música, vídeo, jogo
etc.); para se reproduzir, o vírus se anexa ou se sobrescreve em outros
arquivos do sistema operacional. Para Deitel, Deitel e Choffnes (2005),
os vírus podem ser classificados em três tipos:
a. Vírus de setor de boot (inicialização): infecta o setor de boot do
computador, fazendo com que ele seja inicializado com o sistema
operacional e permitindo o controle do sistema.
b. Vírus transiente: anexo a uma aplicação do computador,
sendo ativado e desativado quando a aplicação é executada ou
encerrada, respectivamente.
c. Vírus residente: fica armazenado na memória do computador,
agindo enquanto o computador estiver em funcionamento.
Uma possível forma de disseminação do vírus ocorre quando ele
acessa uma aplicação de correio eletrônico instalada no computador
infectado. O vírus usa a lista de contatos da aplicação e gera e-mails
falsos, no qual ele se insere como anexo, que ao ser aberto pelo destinatário
infecta o computador. Uma possível ação para minimizar esse
146 Sistemas Operacionais
tipo de disseminação é o uso de um antivírus, que examina os anexos
dos e-mails recebidos, evitando o recebimento de e-mails maliciosos.
Outra ação preventiva é a conscientização do usuário em não abrir
e-mails enviados por desconhecidos ou e-mails suspeitos.
Um verme (worm) é um código executável que se propaga em uma
rede infectando outros arquivos. Diferentemente do vírus, o verme não
necessita da ação de um usuário ou de ser anexado a um arquivo; basta
ter acesso a uma rede para conseguir rapidamente infectar os seus
computadores. O verme se propaga buscando encontrar vulnerabilidades
dos softwares e dos sistemas operacionais que, ao serem descobertas,
permitem a ele agir desativando um computador ou todos os
que estão conectados a uma rede.
O antivírus pode atuar no combate aos vírus e vermes, porém ele é
uma aplicação reativa, pois consegue atuar somente com vírus e vermes
conhecidos, sendo ineficiente contra vírus que não fazem parte da
sua base de dados.
Cavalo de Troia (Trojan Horse) é um programa mal-intencionado que
tem autorização para ser executado no sistema operacional, o que dificulta
a sua identificação, visto que ele se assemelha aos programas do
computador.
O programa de porta dos fundos (backdoor) é um vírus que permite
ao atacante o acesso completo aos recursos do computador
infectado. Ele pode ser utilizado para capturar as senhas, os dados
de cartão e outros dados sigilosos que são digitados pelo usuário do
computador infectado.
Quando é realizado um ataque de recusa de serviço (Denial-of-
-Service – DoS), os invasores enviam muitos pacotes de dados contra
servidores, saturando-os e impedindo que as solicitações dos verdadeiros
usuários sejam atendidas. Os ataques de recusa de serviço podem
levar à queda ou desconexão dos computadores atacados, comprometendo
sites Web ou até mesmo sistemas críticos. Esses ataques não
afetam os dados armazenados nos servidores atacados, porém o tempo
de indisponibilidade de serviço pode trazer altos prejuízos para os
seus responsáveis.
O ataque de sistema de nome de domínio (Domain Name System –
DNS) busca alterar o endereço utilizado por um site Web, redirecionando
os usuários para outro site, semelhante ao original, no qual os
Segurança em sistemas operacionais 147
usuários desavisados irão revelar dados sigilosos, como os seus logins
e senhas de acesso.
O ataque de recusa de serviço distribuído ocorre quando os pacotes
de dados são enviados de vários computadores, simultaneamente. Em
muitos casos, esses computadores estão contaminados por um vírus,
que permite ao invasor utilizar os seus recursos para efetuar o ataque.
Esse tipo de ataque torna difícil a identificação do seu autor, visto que
ele não é executado pelo computador do invasor.
Uma das atividades mais executadas pelos crackers é a exploração
de vulnerabilidades das aplicações instaladas em um servidor. Essa ação
torna muito difícil a vida dos administradores, em virtude do elevado
número de aplicações instaladas, somado à descoberta diária de vulnerabilidades,
fazendo-os depender da parceria e agilidade por parte
dos desenvolvedores de software para criar/gerar possíveis correções.
Um ataque que utiliza essa estratégia é o transbordamento de buffer,
que ocorre quando um programa envia mais dados a um buffer do
que ele consegue armazenar, substituindo os dados corretos por código
mal-intencionado que pode permitir ao invasor acesso ao sistema.
Livro
Para um melhor entendimento
sobre como
funciona o gerenciamento
de segurança
implementado no sistema
operacional Linux, leia a
obra Sistemas Operacionais
com Java.
GAGNE, G.; SILBERSCHATZ, A.;
GALVIN, P. 7. ed. Elsevier, 2008.
Para Deitel, Deitel e Choffnes (2005), uma invasão de sistema é
uma violação bem-sucedida da segurança do computador por um
usuário externo não autorizado.
Uma forma de ataque popular entre os crackers é a desfiguração da
Web, quando os invasores conseguem acessar, ilegalmente, o site Web
de uma organização e alteram o seu conteúdo.
A utilização do Cavalo de Troia, de um programa de porta dos fundos
ou mesmo uma vulnerabilidade de um programa ou do sistema operacional
permite aos invasores acessarem servidores, por exemplo, explorando
as falhas das aplicações de servidores Web, como o Microsoft Internet
Information Services (IIS) ou o Apache HTTP Server; ou os computadores
pessoais, por exemplo, explorando as falhas dos browsers.
5.5 Prevenção de ataques e
Vídeo soluções de segurança
Mesmo diante da grande variedade de ameaças à segurança dos
sistemas e computadores, os profissionais de segurança usam solu-
148 Sistemas Operacionais
ções de software e hardware para evitar e/ou minimizar possíveis ataques,
que serão descritos nesta seção.
Um firewall realiza a proteção de uma rede local (Local Area
Network – LAN), gerenciando o seu tráfego e impedindo a invasão por
pessoas não autorizadas (Figura 10). Ele pode atuar proibindo todas as
transmissões que não possuem uma permissão explícita para serem
realizadas, o que proporciona um alto grau de segurança, mas pode
impedir o tráfego de dados legítimos no sistema; ou permitindo todas
as transmissões que não possuem uma proibição explícita, o que deixa
o sistema mais vulnerável a ataques, porém não impede o tráfego de
dados legítimos no sistema. Para se conectar à internet, a LAN faz uso
de um gateway (portal), que utiliza o firewall como forma de segurança.
Figura 10
Firewall protegendo uma LAN com três computadores
207.68.160.190:80 207.68.160.191:25 207.68.160.192:21
Firewall
Servidor
Web
Servidor de
Servidor de
FTP
Conexão
com a rede
Rede local
Fonte: Tanenbaum; Bos, 2015, p. 404.
Segundo Deitel, Deitel, e Choffnes (2005), há dois tipos primários
de firewall:
Firewall de filtragem de
pacotes: examina os pacotes
que são enviados de fora da
rede, com base em regras
como a origem do pacote, do
endereço ou da porta. Uma
desvantagem nesse tipo de
firewall é que ele avalia somente
a origem do pacote de dados,
sem levar em conta os dados
anexados à mensagem, o que
pode permitir a entrada de vírus
no sistema.
Gateway de nível de
aplicação: busca proteger
a rede contra os dados
contidos nos pacotes.
Caso o pacote recebido
contenha um vírus, ele será
identificado pelo gateway,
que vai impedir o seu envio
para o destinatário.
Segurança em sistemas operacionais 149
A utilização de um firewall é considerada um dos modos mais simples
e efetivos de se aumentar a segurança em redes de pequeno porte.
A Microsoft incluiu um software de firewall em seus sistemas operacionais
com o Windows XP, batizando-o de Windows Firewall. Em sua
versão mais recente, o Windows 10, o software é chamado de Windows
Defender Firewall.
Uma solução complementar ao uso do firewall é o uso da tecnologia
de camada de ar, que separa a rede interna da rede externa, impedindo
que os usuários externos vejam a estrutura de rede interna, evitando
que os hackers consigam analisar a rede, procurando por seus pontos
fracos. Essa tecnologia é utilizada por empresas de comércio eletrônico
da modalidade business-to-business (B2B), que permitem aos seus clientes
compartilharem informações de estoque com seus fornecedores,
que passam a atuar de maneira digital e segura.
Um sistema de detecção de intrusos (Intrusion Detection Systems
– IDS) monitora os arquivos de registro (log files) gerados pela rede,
pelos computadores ou pelas aplicações, procurando por comportamentos
suspeitos, alertando os administradores da rede e, automaticamente,
interrompe a execução do processo suspeito. Os arquivos
de log armazenam informações sobre o comportamento do sistema,
como o horário em que os serviços do sistema operacional são solicitados
e o nome do processo solicitante.
Os sistemas de detecção de intrusos baseada no hospedeiro monitoram,
continuamente, os arquivos de log gerados pelo sistema operacional
e suas aplicações, buscando detectar possíveis ameaças, como
o Cavalo de Troia.
Já os sistemas de detecção de intrusos baseada na rede monitoram,
continuamente, o tráfego da rede, buscando detectar padrões
fora do comum, que poderiam indicar um ataque DoS ou a tentativa
de acesso à rede sendo feita por um usuário não autorizado. Empresas
como a Cisco, HP e a Symantec comercializam soluções de detecção de
intrusos. Há também iniciativas de software livre nesse sentido, como
o projeto Snort.
A detecção de intrusos utiliza técnicas como a análise estática, na
qual cria um modelo de comportamento esperado para as aplicações,
que compara esse modelo com um comportamento anômalo, gerado
pela tentativa de ataque de um cracker.
150 Sistemas Operacionais
Desde a década de 1990, o número de vírus aumentou significativamente,
ameaçando a segurança dos usuários em suas residências, nos
seus trabalhos e gerando prejuízos na casa dos bilhões para as empresas.
Como resposta a essa ameaça crescente, os softwares antivírus buscam
proteger os computadores contra os vírus, identificando-os e eliminando-
-os. Apesar do uso de diferentes técnicas para a detecção e eliminação dos
vírus que possam estar atuando em um sistema, os softwares antivírus
não conseguem garantir a proteção completa para o computador.
De acordo com Deitel, Deitel e Choffnes (2005), os softwares antivírus
empregam as seguintes técnicas de detecção:
a. Detecção de vírus por verificação de assinatura: usa uma
lista de vírus conhecidos, uma região que não muda durante a
propagação do vírus. Para identificar o vírus, o software compara os
arquivos com as assinaturas contidas em sua lista. Desvantagens:
crescimento da lista, em virtude do aumento constante do número
de vírus; necessidade de atualização constante da lista; não
identificação de vírus, que não estão contidos na lista; ineficácia
na avaliação de vírus variante, que teve o seu código modificado
quanto ao vírus original, mas continua sendo perigoso; ineficácia
na avaliação de vírus polimórfico 4 (Figura 11).
4
Vírus polimórfico é um vírus
que modifica o seu código de
acordo com sua propagação,
dificultando a sua identificação
pela lista de assinaturas.
Figura 11
Propagação por vírus polimórfico
2ª geração
Criptografia
Assinatura
Vírus típico
Vírus polimórfico
1ª geração
Carga
explosiva
criptografada
Código inofensivo
Carga explosiva
Variável
Assinatura
Código inofensivo
Algoritmo de
polimorfismo
Adicionar no-ops
Carga explosiva
Assinatura
Código inofensivo
Variável
Carga explosiva
Código inofensivo
Variar instruções
e/ou ordem
Carga explosiva C
Carga explosiva A
Carga explosiva B
Novas instruções
Assinatura
Fonte: Tanenbaum; Bos, 2015, p. 582.
Nota: todas as três técnicas podem ser combinadas
Segurança em sistemas operacionais 151
b. Verificação heurística: tem como base a forma com que o
vírus se replica, como ele reside na memória e/ou no seu código
malicioso. Ao usar essas informações, o software consegue
detectar vírus ainda não identificados, porém pode estar sujeito
a resultados falsos.
c. Verificação de consistência: com base na premissa de que
um vírus precisa modificar os arquivos de um computador para
infectá-los, mantém um registro de consistência dos arquivos
considerados essenciais para o sistema. Sistemas operacionais,
como o Windows XP, realizam verificações de consistência dos
seus arquivos essenciais substituindo-os diante de uma alteração
para evitar um possível dano ao sistema.
d. Verificação de tempo real: técnica em que os softwares são
alocados na memória do computador, impedindo a infecção por
vírus de maneira ativa.
Buscando melhores resultados, os softwares antivírus, em sua
maioria, usam uma combinação dessas duas formas de detecção, por
assinatura e heurística.
Um ponto negativo das falhas de segurança dos sistemas operacionais
é que muitas delas somente são descobertas após o sistema
estar em uso. Como exemplo das ações possíveis, temos a proposta do
projeto Berkeley Software Distribution (BSD) UNIX, OpenBSD, que é ser
a distribuição UNIX mais segura possível. A equipe do projeto realiza as
seguintes atividades:
Pesquisas sobre possíveis falhas
de segurança, feitas por uma
equipe de auditoria.
SurfsUp/Shutterstock
Liberação de correções de
segurança (security patch) para as
falhas identificadas.
Criação de linhas de comunicação
com os usuários por meio de um
fórum público.
152 Sistemas Operacionais
Tanto o OpenBSD quanto o Apple MacOS X mantêm todas as suas
portas fechadas, além de desativar os serviços de rede, que poderão
ser habilitados pelo usuário posteriormente.
A Microsoft aplica correções de segurança chamadas hotfixes
(reparos a quente) para os seus sistemas operacionais, que são
oferecidos aos usuários por meio do software Automatic Updates
(Atualizações Automáticas).
A política de controle de acesso protege os dados armazenados em um
arquivo do sistema, porém isso não se aplica quando o arquivo é acessado
por um outro sistema operacional, por exemplo, se um arquivo é gerado no
Windows XP e copiado para um pen drive para ser acessado em um outro
computador com Linux. Diante dessa possibilidade, os sistemas operacionais
passaram a suportar sistemas de arquivos seguros que protegem os
dados sensíveis dos arquivos, independentemente da forma com que ele é
acessado. O Windows XP utiliza a Nova Tecnologia de Sistema de Arquivos
(New Technology File System – NTFS) para proteger seus arquivos por meio
de criptografia e controle de acesso.
O sistema de arquivos NTFS usa o sistema de criptografia de arquivos
(Encrypting File System – EFS) para proteger os arquivos e as pastas
do sistema. O EFS utiliza criptografia por chave secreta e por chave
pública para garantir que os arquivos protegidos não sejam acessados
por um usuário indevido, caso o computador seja roubado ou perdido.
A criptografia pode ser aplicada tanto em arquivos quanto em pastas,
que terão todo o seu conteúdo criptografado. O seu uso em pastas
alcança um nível de segurança mais elevado, pois impede que as aplicações
criem arquivos temporários no seu interior.
Em 1985, o Departamento de Defesa (Department of Defense –
DoD) dos EUA publicou um documento oficialmente intitulado Critérios
Confiáveis de Avaliação de Sistemas de Computador (Department of Defense
Trusted Computer System Evaluation Criteria), que ficou conhecido
como Livro Laranja (Orange Book), escrito para classificar em quatro os
níveis de segurança dos sistemas operacionais, de A a D, em ordem
decrescente de segurança. Conforme Deitel, Deitel e Choffnes (2005),
as características de cada nível são:
a. Nível D (proteção mínima): armazena qualquer sistema
operacional que não cumpra os requisitos dos outros níveis,
sendo considerados inseguros.
Segurança em sistemas operacionais 153
b. Nível C (proteção discricionária): compreende dois subníveis,
C1 e C2. Os sistemas operacionais enquadrados no subnível C1
precisam que seja informado um usuário ou um grupo, acrescido
de uma senha, para obter acesso ao sistema. As primeiras versões
do UNIX pertenciam ao subnível C1. O subnível C2 suporta o
acesso com um usuário e uma senha. Sistemas operacionais
como o Windows NT, UNIX mais modernos e o IBM OS/400
pertencem ao subnível C2.
Dica
No filme Jogos de Guerra,
Matthew Broderick interpreta
um adolescente que invade
um sistema achando que é um
videogame, sem saber que
se trata do sistema de defesa
dos EUA.
Esse é um ótimo filme para que
você compreenda um pouco
mais as atividades de segurança
e prevenção de ataques a
sistemas. O termo firewall foi
utilizado pela primeira vez nesse
longa-metragem.
Direção: John Badham. São
Paulo: MGM, 1983.
c. Nível B (proteção mandatória): compreende três subníveis. No
primeiro subnível, o B1, o sistema operacional deve possuir um
esquema de permissão central predefinido e aplicar etiquetas
de sensibilidade aos sujeitos e aos objetos. O subnível B2 exige
que a comunicação entre o usuário e o sistema operacional ao
realizar a autenticação seja segura, somados aos requisitos do
subnível B1. O subnível B3 exige que o sistema operacional
implemente domínios de proteção, que concede ao sistema
mecanismos de recuperação seguros e o monitoramento dos
acessos aos sujeitos e aos objetos, para análise futura, somados
aos requisitos do subnível B2.
d. Nível A (proteção verificada): compreende dois subníveis, o
subnível A1, que exige a verificação formal da segurança do
sistema operacional, somados aos requisitos do subnível B3; e o
subnível A2, que ainda não foi definido.
O Orange Book é considerado um documento ultrapassado, mas representa
um marco na padronização e busca por um ambiente computacional
seguro. A existência de um padrão permite ao usuário tomar
a ciência da proteção e da segurança aplicadas às suas informações.
5.6 Comunicação e protocolos de segurança
Vídeo Com o aumento do uso da internet por parte dos usuários, em especial
com o crescimento das operações de comércio eletrônico, dados
sensíveis passaram a ser transmitidos em um volume crescente, exigindo
que as aplicações fornecessem meios de conexão seguras para evitar
154 Sistemas Operacionais
o furto e o uso indevido desses dados. Segundo Deitel, Deitel e Choffnes
(2005), há cinco requisitos para uma operação bem-sucedida e segura:
a. Privacidade: busca a garantia de que a informação transmitida
pela internet não será capturada ou entregue sem a sua
autorização e conhecimento à outra pessoa.
b. Integridade: busca assegurar que a informação enviada ou
recebida em uma operação não será comprometida ou alterada.
c. Autenticação: analisa a forma com que o emissor e o receptor
da operação realizam a verificação das suas identidades.
d. Autorização: analisa a forma com que o sistema operacional
gerencia o acesso aos seus recursos protegidos, fazendo uso
das credenciais do usuário – identidade (login) e a prova da
identidade (senha).
e. Não rejeição: busca provar, de modo legal, que uma mensagem
foi enviada ou recebida durante uma operação.
Somado a esses cinco requisitos, a segurança de redes deve se
preocupar como a questão da disponibilidade, como assegurar que
os computadores interligados por uma rede conseguirão se conectar
de maneira contínua.
Mesmo diante da flexibilidade e confiabilidade conferida aos algoritmos
de chave pública, eles não são considerados eficientes quando
tratamos do envio de grandes quantidades de dados, não sendo considerados
substitutos dos algoritmos de chaves secretas. Chamamos
de protocolo de acordo de chaves quando duas partes precisam trocar
chaves usando um meio considerado inseguro.
O envelope digital é considerado a forma mais simples de utilizar
o protocolo de acordo de chaves e ocorre quando a mensagem é criptografada
por uma chave secreta; esta é criptografada por uma chave
pública e anexa à mensagem que é enviada. Ao receber a mensagem
(envelope), o receptor decripta a chave secreta utilizando uma chave
privada; de posse da chave secreta, ele a usa para decriptar a mensagem
(Figura 12). A segurança dessa operação vem do fato de o emissor
ter a certeza de que somente o receptor conseguirá decriptar a chave
secreta e com ela ler a mensagem.
Segurança em sistemas operacionais 155
Figura 12
Criação de um envelope digital
1
Emissor
Criptografa
Compre 100 ações
da empresa X
Texto comum
Chave
simétrica
secreta
XY%#?42%Y
Texto cifrado
3
2
Criptografa
Envelope
digital
Chave
simétrica
secreta
Chave pública
do receptor
Chave
simétrica
secreta
criptografada
Receptor
Fonte: Tanenbaum; Bos, 2015, p. 587.
Uma das grandes dificuldades para a manutenção da segurança do
sistema criptográfico é manter as chaves privadas em segredo, pois, ao
serem mal gerenciadas, utilizadas de modo incorreto, podem ocasionar
um número de violações superior ao dos ataques criptoanalíticos.
Um ponto a ser observado é a geração da chave, ou seja, o modo
como a chave é criada. Se ao desenvolver o algoritmo de criação de chave
o programador optar por utilizar um pequeno subconjunto de chaves
possíveis, o algoritmo se tornará um possível alvo de ataques de força
bruta. Como solução para esse problema, o programador deverá operar
um subconjunto com o maior número de resultados possíveis e aleatórios,
dificultando a realização de um ataque de força bruta.
5
TCP/IP é um conjunto de protocolos
de comunicação utilizados
por computadores interligados
por uma rede.
Considerado uma forma de garantir a comunicação entre dois computadores
interligados pela internet, o protocolo de camada segura de
soquetes (Secure Sockets Layer – SSL) foi desenvolvido pela Netscape
Communications, atuando entre o protocolo TCP/IP 5
e o software da
aplicação. O SSL foi substituído pelo protocolo de segurança de camada
de transporte (Transport Layer Security – TLS), eles se diferenciam
pela implementação do algoritmo e pela estrutura dos pacotes utiliza-
156 Sistemas Operacionais
dos. Mesmo protegendo a informação durante a comunicação entre o
cliente e o servidor de comércio eletrônico, tanto o SSL quanto o TLS
não são responsáveis pelos dados sensíveis que são armazenados no
servidor de comércio eletrônico que está sujeito a um ataque.
Uma outra forma de garantir comunicação segura utilizando
conexões públicas é fazer o uso de redes virtuais privadas (Virtual
Private Network – VPN), que estabelecem um canal de comunicação
seguro (túnel), o qual permite o tráfego de dados pela internet.
O túnel é criado com o protocolo de segurança da internet (Internet
Protocol Security – IPSec), desenvolvido pela Força Tarefa
de Engenharia da Internet (Internet Engineering Task Force – IETF),
que usa uma chave pública e criptografia simétrica para que os dados
sejam transmitidos de maneira íntegra e confidencial, além de
autenticar as partes envolvidas.
Para Deitel, Deitel e Choffnes (2005), a segurança da VPN tem como
base três conceitos:
a. Autenticação do usuário: feita pelo cabeçalho de autenticação
(Authentication Header – AH), que anexa informações a cada um
dos pacotes, validando a identidade do emissor e garantindo que
os dados não sejam modificados durante o seu trajeto.
b. Criptografia dos dados: feita pelo protocolo de segurança de
encapsulamento de carga útil (Encapsuling Security Payload
– ESP), que realiza a criptografia dos dados utilizando chaves
simétricas.
c. Acesso controlado ao túnel: feito por meio do protocolo de
troca de chaves da internet (Internet Key Exchange – IKE), que
permite a troca segura das chaves.
Para fazer uso de uma VPN, os usuários necessitam realizar a instalação
de software e/ou hardware especializados que suportam o IPSec.
Cada vez mais os dispositivos conectados por fio têm sido substituídos
pelos dispositivos que permitem aos usuários transmitirem
dados sem fio, que, além da largura de banda e capacidade de processamento
limitados, da alta latência e das conexões instáveis, permitem
que os dados transmitidos sejam acessados mais facilmente
do que a transmissão com fio.
Buscando melhorar esse cenário, o padrão IEEE 802.11 definiu as
especificações para as redes sem fio, aplicando o protocolo de privaci-
Segurança em sistemas operacionais 157
dade equivalente à das redes com fio (Wired Equivalent Privacy –
WEP), que visa proteger as comunicações entre dispositivos sem fio
por meio da criptografia dos dados transmitidos e não permitindo
o acesso de usuários não autorizados à rede sem fio. Infelizmente,
a segurança do protocolo WEP é considerada insuficiente, uma vez
que sua chave secreta pode ser quebrada por um ataque de força
bruta, somado ao fato de que as redes sem fio, que usam o WEP,
compartilham uma única chave secreta com vários usuários, sem
alterá-la por um longo período.
Procurando solucionar as deficiências do WEP, em 2003, o IEEE e a
Wi-Fi Alliance desenvolveram a especificação acesso protegido Wi-Fi
(Wi-Fi Protected Access – WPA), que introduziu a criptografia de chave
dinâmica exclusiva para cada um dos usuários, além de fornecer
autenticação dos usuários, usando um servidor para armazenar as
credenciais.
A técnica conhecida como esteganografia (escrita oculta, em grego)
consiste na ocultação de informações dentro de outra, que pode ser
uma mensagem, uma imagem, um arquivo multimídia etc. A esteganografia
tem sido utilizada como solução para a proteção da propriedade
intelectual por meio de marcas-d’água digitais, que podem ser visíveis ou
não. As marcas-d’água digitais podem ser inseridas nas músicas e imagens
digitais, permitindo verificar se elas foram copiadas.
Ao falarmos de segurança de software, podemos dividir a produção
de software em dois grupos: os defensores de código-fonte aberto e
os defensores do software proprietário. Para os defensores do código
aberto, a segurança do software proprietário ocorre somente por
causa da ocultação do seu código-fonte. Do outro lado, os defensores
de software proprietário alegam que o seu código-fonte não pode ser
analisado pelos invasores em busca de vulnerabilidades.
Um dos pilares do código-fonte aberto é a colaboração, que permite
a vários usuários participarem e contribuírem com os projetos em
que estão envolvidos. Para os defensores do código aberto, as soluções
proprietárias não desfrutam dessa vantagem, na qual os colaboradores
poderiam procurar de maneira mais eficiente pelas falhas de
segurança e apresentar novas soluções. Rebatendo essa crítica, os desenvolvedores
de software proprietário alegam que as suas baterias de
teste são suficientes e são realizadas por especialistas.
158 Sistemas Operacionais
Outra queixa feita pelos defensores de código-fonte aberto é
que os desenvolvedores de software proprietário não divulgam publicamente
suas falhas de segurança, mesmo que uma correção
tenha sido fornecida, uma vez que isso pode prejudicar a imagem
da empresa perante seus usuários.
Como vantagem das aplicações de código-fonte aberto podemos
citar a interoperabilidade, que permite a inclusão de padrões
e protocolos criados pela comunidade nos seus produtos de
software. Isso também favorece os usuários, que podem customizar
os níveis de segurança das suas aplicações. Já os usuários de
software proprietário ficam restritos às configurações sugeridas
pelo fabricante do software ou a adquirir outros produtos para
conseguir operar novas funcionalidades.
Uma outra vantagem das aplicações de código-fonte aberto é
que as suas aplicações estão disponíveis para avaliação e testes
por parte da sua comunidade. Já as soluções proprietárias estão
atadas a um registro histórico de segurança ou dependem do aval
da sua equipe de especialistas.
Uma desvantagem das aplicações de código-fonte aberto é que
as soluções não vêm com uma configuração padrão de segurança
ao serem instaladas, o que pode comprometer o sistema, pela negligência
ou mesmo ignorância do usuário sobre esse assunto. Por
exemplo, várias distribuições Linux possuem serviços de rede habilitados,
que podem tornar o computador alvo de ataques externos.
Entre as distribuições UNIX, o OpenBSD possui uma configuração
padrão de segurança na sua instalação.
Os sistemas proprietários já vêm com uma configuração padrão
de segurança ao serem instalados. Eles podem ser tão seguros
quanto os de código-fonte aberto.
Dica
Para um melhor
entendimento sobre a
comunicação de dados
e como ela influencia o
surgimento de protocolos
de segurança para evitar
os ataques e furtos de
dados, assista ao vídeo
SSL / TLS – dicionário do
programador, publicado
no canal Código Fonte TV.
Disponível em: https://
www.youtube.com/
watch?v=eOsGqXy2vmA. Acesso
em: 7 ago. 2020.
CONSIDERAÇÕES FINAIS
Neste capítulo, aprofundamos nossa visão sobre a segurança do computador.
A evolução do hardware e do software nem sempre minimizam
as preocupações dos administradores de redes e especialistas de segurança
no que se refere às possíveis oportunidades para invasão, destruição
e furto de dados sensíveis dos computadores.
Segurança em sistemas operacionais 159
Os projetistas de sistema precisam se preocupar com a criptografia
dos dados, que normalmente são transmitidos pela internet, via digital
mais utilizada para troca de informação. Além disso, precisam garantir
que os emissores e receptores dos dados realmente são quem dizem ser.
Cada vez mais surgem novas ameaças aos serviços, sistemas e dados
sensíveis; os invasores buscam por fraquezas e realizam ataques das
mais diferentes formas. Isso precisa ser prevenido, os sistemas devem
ser defendidos e respondidos pelos administradores e especialistas de
segurança. Ao mesmo tempo, as organizações procuram definir padrões
e protocolos para tornar as atividades computacionais mais seguras.
Os pontos abordados neste capítulo não são definitivos, visto que essa
disputa ainda não chegou ao fim, pois as partes envolvidas, sejam elas atacantes,
sejam defensoras, continuam crescendo e procurando adiantar
quais são os possíveis passos dos seus adversários.
Os atacantes são beneficiados pelas demandas crescentes dos usuários,
que levam às modificações constantes por parte dos desenvolvedores
de software e acabam criando novos cenários, com novos desafios
para a segurança dos sistemas operacionais.
ATIVIDADES
1. O que é um sistema de criptografia por chave secreta ou chave
simétrica?
2. Por que os algoritmos de chave pública são chamados de funções de
uma via ou de armadilha?
3. O que são bombas lógicas?
REFERÊNCIAS
DEITEL, H. M.; DEITEL, P.; CHOFFNES, D. Sistemas operacionais. 3. ed. Trad. de Arlete Simille
Marques. São Paulo: Pearson, 2005.
TANENBAUM, A.; BOS, H. Sistemas Operacionais Modernos. 4. ed. São Paulo: Pearson
Universidades, 2015.
160 Sistemas Operacionais
GABARITO
1 Introdução aos sistemas operacionais
1. Os sistemas operacionais não eram necessários, pois a interação dos
programadores com essas máquinas era feita por meio de chaves
mecânicas, nas quais se introduziam os comandos bit-a-bit, a fim de
que esses fossem convertidos em uma linguagem que a máquina
pudesse compreender.
2. O desenvolvimento do transistor e das memórias magnéticas marcou
o começo da segunda fase de computadores, que abrangia aqueles
construídos entre 1955 e 1965. A substituição das válvulas, da
primeira fase, pelo transistor trouxe velocidade e confiabilidade ao
processamento. Já a criação das memórias magnéticas garantiu que os
dados fossem acessados mais rapidamente, aumentou a capacidade
de armazenamento e permitiu que o tamanho dos computadores
fosse reduzido.
3. Buscando solucionar o problema de performance e de armazenamento,
a IBM lançou a série 360, composta de máquinas compatíveis entre
si. A série começava com o modelo 1401, um computador menos
potente, e chegou até o 7094, o computador mais potente da série.
A diferença entre os computadores da série 360 estava no preço e na
performance, em virtude da quantidade de memória, da velocidade do
processador, do número de dispositivos de E/S etc. A compatibilidade
dos programas a serem executados nos computadores dessa série
era garantida por uma arquitetura comum entre eles e pelo mesmo
conjunto de instruções básicas. Com a série 360, a IBM conseguia unir,
em um mesmo conjunto de computadores, a utilização tanto para uso
científico como para uso comercial.
4. Os sistemas operacionais TSS, Multics e CP/CMS incorporavam o
conceito de memória virtual, em que os programas conseguiam
endereçar mais localizações de memória do que as providas pela
memória principal, também chamada de memória real ou física.
Isso permitia que os programadores se preocupassem com o
desenvolvimento das aplicações e não precisassem mais atuar no
gerenciamento de memória.
Gabarito 161
5. Um sistema é considerado crítico em negócios quando falha e pode
resultar em perdas econômicas significativas para a empresa que
o utiliza. Podemos citar, como exemplos, os servidores web e os
servidores de bancos de dados.
2 Interação do sistema operacional com hardware e
software
1. A maneira mais simples de se armazenar um arquivo em um sistema
operacional é considerá-lo uma sequência de bytes, na qual o sistema
operacional não se preocupa com o conteúdo do arquivo, deixando a
responsabilidade da sua identificação com o usuário.
2. O UNIX faz uso dos arquivos especiais de caracteres para se comunicar
com os dispositivos de E/S.
3. O UNIX faz uso dos arquivos especiais de blocos para se comunicar
com os discos.
4. Diretório-raiz é a forma mais simples de utilização de diretório quando
o sistema operacional faz uso de somente um para armazenar todos
os seus arquivos.
5. A utilização do firmware permite aos fabricantes de dispositivos
que utilizem chips programáveis, de uso geral, em vez de utilizarem
hardware de uso personalizado. Isso resulta em economia de custos,
além de facilidade de inovação e de implantação, pois se torna mais
fácil adicionar uma funcionalidade por meio de uma alteração do
firmware do que com a substituição do chip.
3 Processos e threads
1. O espaço de endereçamento do processo é formado por uma região
de texto que armazena o código que o processador executa; uma
região de dados que armazena as variáveis e a memória alocada
dinamicamente durante a execução do processo; e uma região de pilha
que armazena as instruções e as variáveis locais para chamadas ativas
ao procedimento, que fazem a pilha crescer quando são emitidas, e
diminuir quando o procedimento retorna às chamadas.
2. A diferença entre um processo em estado de execução e um processo
em estado de pronto é que o processo em execução está sendo
executado pelo processador, enquanto o processo em estado de
162 Sistemas Operacionais
pronto informa ao sistema operacional que já pode ser executado e
precisa ser alocado em um processador.
3. O bloco de controle de processo (PCB) é um conjunto de informações
do processo que auxiliarão o sistema operacional a gerenciá-lo.
4 Memória real e virtual
1. A estratégia de busca determina qual próxima parte de um programa
ou de um conjunto de dados será transferida para a memória principal.
2. A estratégia de posicionamento determina qual lugar da memória
principal deverá ser ocupado pelos programas e dados que estão
chegando.
3. A estratégia de substituição determina quais dados deverão ser
removidos da memória principal para liberar espaço para um novo
programa.
4. Os endereços virtuais são referenciados pelos processos e os
endereços físicos indicam as localizações físicas na memória principal.
5. A MMU é responsável por identificar o endereço real correspondente
ao endereço virtual acessado por um processo.
5 Segurança em sistemas operacionais
1. A criptografia por chave secreta, ou criptografia simétrica, é um sistema
que utiliza a mesma chave secreta tanto para criptografar quanto
decriptar um texto.
2. A ação de cifrar uma mensagem utilizando uma chave pública não
requer muitos recursos computacionais. Entretanto, realizar a sua
decriptação sem ter acesso à chave privada necessita de tempo e
recursos computacionais elevados.
3. As bombas lógicas são códigos inseridos no sistema operacional de
produção da empresa que dependem da inserção diária de uma
senha para que nada ocorra.
Gabarito 163
Este livro é destinado a uma melhor compreensão
do papel e das atividades desempenhadas pelo
sistema operacional. Para isso, começa com uma
apresentação histórica dos sistemas operacionais,
seus possíveis ambientes, seus componentes e sua
arquitetura. Em seguida, explica a forma com que
o sistema operacional interage com o hardware
e com o software; a execução de tarefas pelos
sistemas operacionais; a conversão de processos
em threads; o armazenamento em memória real e
em memória virtual do computador; e, finalmente,
trata da segurança em sistemas operacionais,
as possíveis formas de ataque e defesa dos sistemas
e apresenta técnicas de proteção dos dados
trocados pelos computadores.
Em suma, esta obra traz as informações básicas
para a compreensão do papel dos sistemas operacionais
e destina-se aos estudantes que desejam
aprofundar seus conhecimentos sobre esse coadjuvante
que merece todos os créditos por um
trabalho bem realizado nos nossos computadores.
Código Logístico
Fundação Biblioteca Nacional
ISBN 978-85-387-6615-5
59313
9 788538 766155