04.12.2022 Views

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

e-mail

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!