Você está na página 1de 156

CURSO DE SISTEMAS Fundamentos de

DE INFORMAÇÃO Sistemas Operacionais

www.esab.edu.br
Fundamentos de
Sistemas Operacionais

Vila Velha (ES)


2014
Escola Superior Aberta do Brasil

Diretor Geral
Nildo Ferreira
Diretora Acadêmica
Beatriz Christo Gobbi
Coordenadora do Núcleo de Educação a Distância
Beatriz Christo Gobbi
Coordenadora do Curso de Administração EAD
Rosemary Riguetti
Coordenador do Curso de Pedagogia EAD
Claudio David Cari
Coordenador do Curso de Sistemas de Informação EAD
David Gomes Barboza

Produção do Material Didático-Pedagógico


Delinea Tecnologia Educacional / Escola Superior Aberta do Brasil

Diretoria Executiva Design Educacional


Charlie Anderson Olsen Aline Batista
Larissa Kleis Pereira Evelin Lediani Bao
Margarete Lazzaris Kleis Revisão Gramatical
Conteudista Bárbara Seger Zeni
Alex Magalhães Machado Laís Gonçalves Natalino
Coordenação de Projeto Design Gráfico
Andreza Regina Lopes da Silva Laura Rodrigues
Líderança Técnica Design Educacional Neri Gonçalves Ribeiro
Renata Oltramari Diagramação
Líderança Técnica Design Gráfico Dilsonir José Martins Junior
Fernando Andrade Karina Silveira

Líderança Técnica Revisão Gramatical Equipe Acadêmica da ESAB


Tiago Costa Pereira Coordenadores dos Cursos
Docentes dos Cursos

Copyright © Todos os direitos desta obra são da Escola Superior Aberta do Brasil.
www.esab.edu.br
Av. Santa Leopoldina, nº 840
Coqueiral de Itaparica - Vila Velha, ES
CEP 29102-040
Apresentação
Caro estudante,

Seja bem-vindo à disciplina de Fundamentos de Sistemas Operacionais. Nessa


disciplina vamos estudar o que são sistemas operacionais e que componentes os
constituem. Veremos que sistemas operacionais são a comunicação entre o hardware
da máquina e os programas de computador que costumamos desenvolver. Dessa
forma, esses sistemas operacionais são a base para os outros programas e por isso
influenciam diretamente o desenvolvimento de programas de computador.

Ao longo das próximas 24 unidades, estudaremos o funcionamento desses sistemas


com um grau de detalhes que nos permitirá, ao fim da disciplina, compreender de
forma geral o funcionamento e todos os conceitos relacionados com a estrutura
desses sistemas. Saber como funciona o sistema por trás dos programas de
computador que criamos, nos permite criar melhores programas, que utilizem
melhor os recursos do computador e que possibilitem uma melhor experiência para
os usuários dos programas.

Usando todo o conhecimento que você já adquiriu em outras disciplinas a respeito de


programação e organização de computadores, nesta disciplina poderemos entender
todo o caminho entre o hardware do computador e o usuário.

Veremos também como o sistema operacional gerencia todos os programas do


computador, permitindo que todos executem ao mesmo tempo, utilizem o mesmo
espaço de memória e compartilhem os mesmos recursos de processamento, rede de
comunicação etc.

Fundamentaremos nossos estudos nos trabalhos de renomados autores da área,


como Deitel, Deitel e Steinbuhler (2005), Tanenbaum (2010) e Silberschatz, Galvin e
Gagne (2001).

Bom estudo!
Objetivo
Nesta disciplina vamos estudar os fundamentos dos sistemas operacionais e
quais componentes e ferramentas fazem parte deles. Dessa forma, poderemos
compreender toda a base que gerencia a execução dos programas de computador e
que também gerencia o uso de todos os recursos da máquina.

Através do estudo do funcionamento dos sistemas operacionais, aprenderemos a


criar melhores programas de computador que utilizem de maneira mais eficiente
o que o sistema operacional tem a oferecer. Aprenderemos também a base para
criar nosso próprio sistema operacional ou realizar modificações em sistemas já
existentes.

Habilidades e competências
• Desenvolver aplicações e sistemas computacionais de forma inteligente,
capazes de usufruir com eficácia de todos os recursos do hardware e do sistema
operacional.
• Planejar a implementação de sistemas computacionais de forma que o sistema
operacional possa ser visto como uma extensão da aplicação.
• Auxiliar no desenvolvimento de melhorias para sistemas operacionais existentes
ou na criação de novos sistemas operacionais.
• Compreender o funcionamento de um sistema computacional desde o hardware
até o usuário.
• Entender o papel do sistema operacional, suas virtudes e suas deficiências, de
forma a compreender melhor como usar seus recursos e como compensar suas
fraquezas.
• Analisar aspectos da implementação de aplicações, tirando maior proveito dos
recursos disponibilizados pelo sistema operacional.

Ementa
Histórico e evolução dos sistemas operacionais, princípios e características dos
sistemas operacionais, estrutura de um sistema operacional. Gerenciamento de
processos e threads. Gerenciamento de memória: memória virtual, paginação,
segmentação e swap. Princípios de entrada/saída. Sistema de arquivos. Aspectos
de confiabilidade, segurança e desempenho.
Sumário
1. O que é um sistema operacional?.....................................................................................6
2. Histórico e evolução dos sistemas operacionais – parte 1..............................................12
3. Histórico e evolução dos sistemas operacionais – parte 2..............................................17
4. Princípios de hardware e software.................................................................................23
5. Conceitos de um sistema operacional – parte 1 ............................................................31
6. Conceitos de um sistema operacional – parte 2.............................................................36
7. Introdução a processos...................................................................................................42
8. Gerenciamento de processos – parte 1..........................................................................48
9. Gerenciamento de processos – parte 2..........................................................................53
10. Threads..........................................................................................................................58
11. Escalonamento – parte 1...............................................................................................65
12. Escalonamento – parte 2...............................................................................................70
13. Abstração da memória...................................................................................................79
14. Gerenciamento de memória – parte 1...........................................................................84
15. Gerenciamento de memória – parte 2...........................................................................90
16. Paginação......................................................................................................................97
17. Segmentação...............................................................................................................103
18. Memória virtual...........................................................................................................108
19. Introdução a sistemas de arquivos...............................................................................115
20. Gerenciamento de arquivos e diretórios.......................................................................122
21. Gerenciamento de entrada/saída de dados..................................................................127
22. Modos de operação de entrada/saída de dados...........................................................132
23. Segurança e confiabilidade em sistemas operacionais.................................................137
24. Considerações sobre sistemas operacionais..................................................................143
Glossário.............................................................................................................................149
Referências.........................................................................................................................155
1 O que é um sistema operacional?
Objetivo
Contextualizar o principal objeto de estudo da disciplina, o sistema
operacional. O que ele é e qual sua relação com o hardware e as
aplicações.

Nesta primeira unidade de estudo, com o auxilio do trabalho de


Tanenbaum (2010), vamos introduzir o conceito de sistema operacional
como um todo e apresentaremos dois pontos de vista diferentes a respeito
do que é um sistema operacional.

Como Tanenbaum (2010) afirma, um sistema operacional é um grande


e complexo programa de computador. O sistema operacional forma a
base para todos os outros programas do computador. Ele gerencia todos
os recursos do hardware e fornece meios rápidos e eficientes para que
as aplicações do usuário utilizem esses recursos. A Figura 1 ilustra esse
cenário, mostrando a estrutura de um computador. Acompanhe:

Navegador Leitor de Reprodutor


web e-mail de música
usuário
Modo

Software

Programa de interface
com o usuário
núcleo
Modo

Sistema operacional
Hardware

Memórias e disco Processador Periféricos


Figura 1 – Onde o sistema operacional se encaixa.
Fonte: Adaptado de Tanenbaum (2010).

www.esab.edu.br 6
Note que na parte inferior da imagem aparece o hardware do
computador. Esse hardware consiste em: processador (que também
chamaremos de UCP, sigla de Unidade de Processamento Central, do
termo em inglês CPU – Central Processing Unit), memórias, disco
rígido, conectores de rede, entre outros, como os periféricos: mouse,
teclado, monitor etc. O sistema operacional é o software que se comunica
diretamente com o hardware, controlando e gerenciando seus recursos e,
por isso, aparece acima do hardware na Figura 1. Como todo programa,
o sistema operacional é armazenado no disco rígido, ocupa a memória
durante a execução e tem suas instruções executadas pelo processador.

De acordo com Tanenbaum (2010), é possível classificar os softwares


que são executados em um computador conforme o modo de execução,
que pode ser tanto modo núcleo quanto modo usuário. O modo núcleo,
também chamado de modo kernel, é o modo de execução onde se
tem acesso completo a todos os recursos do hardware, sem limitações.
Essa falta de limitações pode ser perigosa, portanto apenas o sistema
operacional é executado em modo kernel.

Em modo usuário, por outro lado, um programa só possui acesso a


um subconjunto dos recursos do hardware. Instruções do processador
que possam causar danos ao sistema, se não usadas corretamente, são
bloqueadas em modo usuário.

Como você pode ver na Figura 1, podemos dividir os programas que são
executados em modo usuário em dois grupos, os programas de interface
com o usuário e os aplicativos que o usuário utiliza. Esses programas
de interface com o usuário costumam ser vistos como parte do sistema
operacional, embora não o sejam. Esses programas servem para permitir
que o usuário controle o sistema operacional, tanto por meio de uma
interface textual quanto gráfica.

Nos sistemas operacionais Windows, por exemplo, podemos citar, como


programas de interface com o usuário, a aplicação Prompt de comando e
o Windows Explorer. No Prompt de comando é possível dar comandos
para o sistema operacional por meio de uma interface textual. No
Windows Explorer, possuímos uma interface gráfica de usuário, também

www.esab.edu.br 7
chamada de GUI (do inglês Graphic User Interface). Um programa com
uma GUI é um programa que possui janelas, botões etc. que facilitem o
uso do programa.

Através desses programas de interface com o usuário, é possível que ele


instale e use os programas que desejar, como navegadores web, leitores de
e-mail ou reprodutores de música.

Por ter que gerenciar todos os recursos do hardware e permitir a execução


dos mais variados programas de computador, os sistemas operacionais
costumam ser programas altamente complexos, com milhões de linhas
de código. Geralmente as instituições que criam sistemas operacionais o
fazem uma vez só, e a partir daí continuam apenas evoluindo seu sistema,
corrigindo falhas e aprimorando funcionalidades.

Para melhor compreender o funcionamento de um sistema operacional, é


possível dividir o conjunto de funcionalidades de um sistema operacional
em dois grupos distintos: (1) as funcionalidades responsáveis por fornecer
aos programas do usuário uma interface simples e eficaz para utilização
dos recursos de hardware, agindo então como uma extensão da máquina;
(2) as funcionalidades responsáveis por gerenciar todos esses recursos de
hardware. Vamos começar estudando o primeiro caso.

1.1 Sistema operacional como uma extensão da


máquina
O hardware de um computador costuma ser muito complexo. Para
controlar um dispositivo de hardware, geralmente se usa comandos em
linguagem de máquina ou assembly, e é preciso ter um conhecimento
aprofundado a respeito do funcionando do dispositivo.

Para complicar ainda mais, cada componente de hardware possui


características próprias que podem variar bastante dependendo do
fabricante. Para controlar diretamente dispositivos de hardware, o
projetista de software precisaria entender a fundo um grande número de
dispositivos e suas peculiaridades de funcionamento.

www.esab.edu.br 8
Controlar e utilizar todos os recursos de hardware de um computador
por parte de uma aplicação do usuário pode então ser uma tarefa
bastante complexa. É preciso que exista algum software entre o hardware
e o usuário com a função de facilitar essa comunicação. O sistema
operacional possui essa função. De acordo com Tanenbaum (2010), ele
possui uma abstração de cada recurso do hardware, que fornece uma
interface facilitada de acesso ao recurso por parte das aplicações.

Ao invés de ter que lidar com endereços de acesso, bits e bytes de


parâmetros e retornos de função e confusas implementações de hardware,
as aplicações de usuário precisam apenas se preocupar em entender a
interface do sistema operacional, que costuma ser muito mais simples.
O sistema operacional fica encarregado, então, de realizar o trabalho
complexo de se comunicar diretamente com o hardware. Nesse cenário,
podemos ver o sistema operacional como uma extensão da máquina,
uma interface entre o hardware e o usuário.

1.2 Sistema operacional como um gerenciador de


recursos
Outro ponto de vista pelo qual podemos ver um sistema operacional
é como um gerenciador de recursos de hardware. Como comentamos
anteriormente, o hardware possui diversos componentes distintos, como
um processador, onde as instruções dos programas são executadas;
memória, onde são armazenados os dados dos programas em execução;
disco rígido, onde todos os dados e programas do computador ficam
sempre guardados mesmo quando o computador é desligado; e vários
periféricos que trocam dados com o computador, como mouse, monitor,
teclado, impressora etc.

Veja que falamos do uso desses recursos sempre no plural, pois existem
diversos programas que são executados ao mesmo tempo no computador,
compartilhando o mesmo processador, usando a mesma memória, o
mesmo disco rígido, enviando trabalhos para a mesma impressora e assim
por diante. De acordo com Tanenbaum (2010), é preciso haver então
algum componente computacional que gerencie o uso desses recursos,

www.esab.edu.br 9
permitindo que eles sejam usados pela maior quantidade possível de
programas e ainda assim sem geração de dados corrompidos ou falhas de
execução. Isto é função do sistema operacional.

É também função do sistema operacional balancear o uso do processador


e de todos os periféricos do computador, permitindo que as instruções de
todos os programas abertos sejam executadas e nenhuma comunicação
com os periféricos seja prejudicada. Ou seja, se dois programas tentarem
usar a mesma impressora ao mesmo tempo, é função do sistema
operacional permitir que os dois trabalhos de impressão ocorram
corretamente, sem que informações de um sejam impressas nas páginas
do outro, por exemplo.

O sistema operacional deve permitir o compartilhamento dos recursos


de hardware, seja em função do tempo ou do espaço. No caso do
processador, esse tipo de compartilhamento se dá por meio do tempo,
onde cada programa possui um período de tempo durante o qual ele
pode utilizar o recurso. Quando um programa está sendo executado pelo
processador e seu tempo termina, o sistema operacional pode ordenar
a interrupção do programa e o início do período de tempo de outro
programa. No caso da memória e do disco rígido, o compartilhamento
ocorre no espaço. Cada programa possui um espaço disponível na
memória e no disco rígido para ele usar como quiser, e o sistema
operacional tem a função de não permitir que uma aplicação mude os
dados na memória de outra aplicação, e vice-versa.

www.esab.edu.br 10
Para sua reflexão
Como dissemos previamente, é função do
sistema operacional gerenciar os recursos
de hardware, inclusive no cenário de vários
programas de computador usando os mesmos
recursos ao mesmo tempo. Esse gerenciamento
é extremamente importante para o recurso de
memória, você consegue entender o porquê?
Como comentamos, uma das funções do sistema
operacional é não permitir que uma aplicação
mude os dados na memória de outra aplicação.
Por que uma aplicação não pode mexer nos
dados de outra? Que riscos existiriam se isso fosse
possível? Imagine cenários em que as aplicações
do computador acessam dados confidenciais,
como contas bancárias. Reflita sobre esse tópico
antes de prosseguir sua leitura.
A resposta a essa reflexão forma parte de sua
aprendizagem e é individual, não precisando ser
comunicada ou enviada aos tutores.

Como você pode perceber, sistemas operacionais são complexos e seu


estudo pode levar muito tempo. Nesta disciplina estudaremos os conceitos
básicos de todas as funcionalidades do sistema operacional, entrando
em detalhes ou tratando algum assunto de forma mais superficial,
dependendo do que for mais conveniente. Na próxima unidade
estudaremos o surgimento e a evolução dos sistemas operacionais, com
foco na primeira e segunda geração. Prossiga com os estudos!

www.esab.edu.br 11
Histórico e evolução dos sistemas
2 operacionais – parte 1
Objetivo
Apresentar o surgimento e a evolução inicial dos sistemas
operacionais, abordando a história da primeira e da segunda geração.

Na unidade anterior iniciamos nossos estudos a respeito dos


fundamentos dos sistemas operacionais. Vimos que um sistema
operacional é o software fundamental de um computador e que ele
executa tarefas complexas, como gerenciar todos os recursos de hardware
do computador e fornecer uma interface fácil e eficiente para que
qualquer programa do usuário possa utilizar esses recursos.

Vimos, também, que sistemas operacionais são complexos e que possuem


milhões de linhas de código. O sistema operacional é executado sempre
em modo núcleo, ou kernel, no qual há total acesso a todos os recursos
do hardware.

Antes de começarmos a explorar todos os detalhes do funcionamento dos


sistemas operacionais vamos, nesta e na próxima unidade, estudar um
pouco sobre a história desses sistemas e entender como eles chegaram ao
estado em que estão hoje. A história dos sistemas operacionais é dividida
em quatro gerações, duas delas estudaremos nesta unidade. Como
Tanenbaum (2010) aponta, a evolução dos sistemas operacionais sempre
esteve relacionada à evolução da máquina em si.

2.1 A primeira geração


De acordo com Tanenbaum (2010), as primeiras máquinas
computacionais digitais começaram a existir ainda no século XIX, porém
foi apenas com a Segunda Guerra Mundial que o desenvolvimento de
computadores digitais realmente recebeu um impulso. Inicialmente,
porém, esses sistemas eram extremamente primitivos. Nessa primeira

www.esab.edu.br 12
geração nem havia a figura de um sistema operacional controlando
o hardware. Na verdade, nem software existia ainda, muito menos
linguagens de programação.

No início, esses computadores faziam uso de diversos componentes


mecânicos, como válvulas. Ao longo dos anos, mais e mais componentes
elétricos e eletrônicos passaram a ser usados, porém ainda de forma
bastante primitiva.

A criação dessas primeiras máquinas durante a Segunda Guerra


Mundial era vista especialmente como estratégia de guerra, portanto
seu desenvolvimento era realizado em segredo. Ainda de acordo com
Tanenbaum (2010), essa primeira geração durou de 1945 a 1955
e nesses dez anos diversos computadores primitivos foram criados
independentemente e totalmente em paralelo, tanto na Alemanha
quanto na Inglaterra e nos Estados Unidos.

Após o fim da guerra, um dos principais exemplares dessa geração


foi finalmente divulgado à imprensa, o Eniac (Eletronic Numerical
Integrator and Computer), um computador eletrônico que pode ser visto
na Figura 2.

Figura 2 – Eniac.
Fonte: Wikimedia Commons (2013).

www.esab.edu.br 13
Como não havia linguagens de programação, todo código era escrito
em linguagem de máquina pura, e a execução de um simples algoritmo
poderia levar horas.

Para executar seu programa, o programador precisava reservar um tempo


para a utilização da máquina, ir até o computador com o programa a
ser executado e os dados que ele usava, geralmente escritos em cartões
perfurados, e então realizar a execução. Os demais computadores da
primeira geração não eram tão diferentes do Eniac. A segunda geração
só se iniciou quando foi inventado um novo componente para os
computadores, o transistor.

2.2 A segunda geração


A invenção do transistor, em meados dos anos 1950, mudou o cenário
dos computadores para sempre. As principais funções de um transistor
são: amplificar ou reduzir um sinal elétrico – funcionalidade muito útil
para as máquinas primitivas que dependiam de mecanismos mecânicos
para realizar tarefas semelhantes. Veja na Figura 3 alguns exemplos de
transistores criados na segunda geração de computadores.

Figura 3 – Exemplos de transistores criados na segunda geração de computadores.


Fonte: Wikimedia Commons (2013).

www.esab.edu.br 14
Como apresentado na Figura 3, os primeiros transistores tinham poucos
centímetros de comprimento. Os transistores criados hoje em dia,
porém, não são mais visíveis a olho nu. Na verdade, existem bilhões deles
dentro dos computadores que usamos no nosso cotidiano.

A principal vantagem do transistor é seu baixíssimo custo de fabricação,


o que permitiu que ele fosse adotado para a fabricação de computadores.

Nessa segunda geração, os computadores passaram a possuir menos


problemas, adquirindo certa estabilidade durante a execução dos
programas. Esse custo mais baixo e a maior estabilidade possibilitaram
as primeiras tentativas de comercializá-los. Porém, de acordo com
Tanenbaum (2010), eles ainda ocupavam salas inteiras e custavam milhões.

Esses computadores eram chamados de mainframes (computadores de


grande porte). Os programas que eram executados nesses mainframes,
diferentemente daqueles da primeira geração, já podiam ser escritos nas
primeiras linguagens de programação, como o Fortran ou assembly.

Os programas eram escritos em papel e depois perfurados em cartões,


como os da Figura 4.

Figura 4 – Dois exemplos de cartões perfurados usados na segunda geração.


Fonte: Wikimedia Commons (2013).

www.esab.edu.br 15
Para executar seu programa, o programador deveria passar esses cartões
para o operador da máquina. Após ordenar a execução do código, o
operador deveria apenas esperar os resultados das computações serem
impressos, para fornecê-los de volta ao programador.

Para agilizar um pouco esse processo, foram criados sistemas em lote, ou


batch. Nesse cenário, o processo de execução dos programas foi dividido
em três etapas. Na primeira etapa, os programas e tarefas eram copiados
para fitas magnéticas usando um computador mais barato. Na segunda
etapa, cada fita, contendo um lote de programas, era passada para o
computador principal que iria de fato executar os programas.

Como esse computador principal precisava executar os vários programas


contidos na fita, nele existia um programa especial, responsável por
começar a execução do primeiro programa da fita e seguir executando
os programas seguintes da fita quando o primeiro terminasse. Esse
programa especial foi a primeira noção de sistema operacional existente.

Através de comandos específicos que o programador informava nos


cartões, era possível informar ao sistema operacional o código do
programa, solicitar a compilação do programa usando o compilador do
Fortran, pedir para o sistema operacional carregar o programa e passar
para ele um conjunto de dados para serem usados.

Por fim, na terceira etapa, os resultados dos programas eram escritos em


outra fita. No fim da execução de todo o lote de programas, essa fita era
transportada para outro computador mais barato, responsável apenas por
imprimir os resultados escritos na fita.

Dessa forma terminamos o estudo da primeira e da segunda geração de


sistemas. Vimos que os primeiros computadores nem possuíam sistemas
operacionais, eram extremamente caros e, ainda assim, primitivos. Na
próxima unidade vamos conhecer a terceira e a quarta geração, momento
em que os sistemas vão finalmente ficar mais parecidos com os que
usamos hoje em dia.

www.esab.edu.br 16
Histórico e evolução dos sistemas
3 operacionais – parte 2
Objetivo
Apresentar a segunda parte da história dos sistemas operacionais,
abordando a terceira e quarta geração e contextualizando o cenário
atual do tema.

Antes de começarmos a nos aprofundar no estudo de sistemas


operacionais, foi necessário começar por uma breve discussão a respeito
da história dos sistemas operacionais, remontando aos seus primórdios,
quando ainda não existia uma figura de um sistema operacional
propriamente dita.

Na unidade anterior vimos como foram a primeira e a segunda geração


de sistemas. Na primeira geração, os computadores ainda eram bastante
primitivos, fazendo uso de diversos componentes mecânicos, como
válvulas. Eles foram desenvolvidos principalmente para uso na Segunda
Guerra Mundial, por isso muitos só vieram a conhecimento da sociedade
após o fim da guerra, como foi o caso do americano Eniac.

Por serem muito grandes e caros, apenas instituições do governo


e grandes universidades possuíam esses computadores e sua
comercialização ainda era inviável. Isso mudou um pouco na segunda
geração, com a invenção do transistor. Por seu custo de fabricação ser
muito pequeno e por ser mais eficiente do que componentes mecânicos
e elétricos, a invenção do transistor mudou muito o cenário da
computação em meados da década de 1950 e finalmente computadores
puderam começar a ser comercializados. Aos poucos foram surgindo
computadores mais modernos, com suporte às primeiras linguagens
de programação, como Fortran e assembly, já possuindo também os
primeiros esboços de um sistema operacional.

www.esab.edu.br 17
Nesta unidade vamos estudar a respeito da terceira e da quarta geração de
sistemas. Veremos que a evolução da máquina e dos transistores permitiu
uma enorme popularização do computador e entenderemos o caminho
que os computadores percorreram até se tornarem objeto essencial na
sociedade atual.

3.1 A terceira geração


A terceira geração de sistemas operacionais iniciou-se por volta de
1965 e terminou por volta de 1980. Nessa fase, os transistores criados
anteriormente começaram a evoluir e começaram a ser usados em
conjunto. Esses conjuntos receberam o nome de circuitos integrados.
Mesmo quando usados em pequena escala, os circuitos integrados já
traziam vários benefícios em desempenho para os sistemas que os usassem.

De acordo com Tanenbaum (2010), um dos principais sistemas


operacionais dessa época é o 360, da IBM. Havia dois grandes nichos
de mercado para os computadores da época: aplicações científicas, que
exigiam cálculos complexos do processador, e aplicações comerciais,
usadas por bancos e outras companhias para ler e ordenar grandes
volumes de dados. Além disso, esses dois nichos de mercado precisavam
de computadores mais baratos por razões econômicas. A ideia do IBM
360 era suprir esses dois mercados com um único produto.

Porém, tornou-se difícil criar um sistema operacional que (1) permitisse


a execução eficiente dos algoritmos científicos que exigiam muito do
processador; (2) permitisse também a execução dos sistemas comerciais
que realizavam inúmeras operações de entrada e saída e, ao mesmo
tempo, que (3) executasse seus programas de forma eficiente tanto
em máquinas poderosas quanto em máquinas básicas e baratas. Eram
diversos requisitos conflitantes e toda a responsabilidade de cumpri-
los recaíam sobre o sistema operacional. Por causa disso, o IBM 360 e
também outros sistemas semelhantes da época possuíam diversos erros e
um código extremamente grande e complexo.

www.esab.edu.br 18
Uma das novidades da terceira geração de sistemas foi a utilização da
multiprogramação, com a qual passou a ser possível executar várias tarefas
do usuário ao mesmo tempo. Por exemplo, enquanto uma tarefa não
estava utilizando a UPC – por estar realizando alguma operação de entrada
ou saída - outra tarefa que desejava utilizar a UPC poderia começar a ser
executada, otimizando a utilização dos recursos do hardware.

Outra novidade na mesma linha de pensamento da multiprogramação


foi a criação do time sharing ou tempo compartilhado. Nesse cenário,
vários usuários se conectam a um único computador através de um
terminal. Isso permitiu que muitos usuários utilizassem os recursos de
um mesmo computador bastante poderoso, compartilhando seus vastos
recursos. De acordo com Tanenbaum (2010), o melhor exemplar da
época de computador que possuía tempo compartilhado é o Multics
– Multiplexed Information and Computing Service, ou Serviço de
Informação e Computação Multiplexadas. Centenas de pessoas poderiam
utilizar seus recursos ao mesmo tempo, o que comercialmente seria
favorável. Porém, o Multics foi um sistema muito à frente do seu
tempo, ou seja, seus criadores enfrentaram problemas computacionais
que ninguém na comunidade científica sabia resolver ainda e por isso o
Multics possuía vários problemas e erros, tornando-se uma plataforma
instável, o que fez com que não se popularizasse.

Porém, o Multics foi usado por Ken Thompson da Bell Labs como
base para a criação de um sistema mais moderno (e sem time sharing),
chamado Unix, que possuía código-fonte aberto, ou seja, totalmente
divulgado para terceiros, e que acabou se tornando bastante popular. Por
possuir código divulgado, diversas versões diferentes de Unix surgiram
em diversos centros de pesquisa, como o System V, da AT&T, e o BSD,
da Universidade da Califórnia em Berkeley.

Com o avanço tecnológico tanto da máquina quanto dos sistemas, em


alguns anos os computadores passaram a ser baratos o suficiente para as
pessoas conseguirem compra-los, o que marcou o fim da terceira geração
e o início da quarta.

www.esab.edu.br 19
3.2 A quarta geração
A quarta geração de sistemas operacionais iniciou-se na década de
1980 e dura até os dias atuais. De acordo com Tanenbaum (2010), a
evolução dos sistemas operacionais na quarta geração seguiu o mesmo
caminho que aqueles da terceira geração: o enorme aumento no uso de
transistores.

Se na terceira geração os computadores possuíam transistores na casa


dos milhares, na quarta geração esse número chegou aos milhões
rapidamente e atualmente já está na casa dos bilhões. Isso significa que o
hardware de um único computador atualmente possui alguns bilhões de
transistores.

Essa explosão no uso de transistores possibilitou uma grande mudança


no cenário da computação mundial: o surgimento do computador
pessoal. Por serem muito pequenos (na casa de milionésimos de
milímetros) e muito baratos, os transistores permitiram uma enorme
redução no custo dos computadores e também uma grande redução no
tamanho deles. Dessa forma, assim como na terceira geração, em que
empresas puderam ter seus próprios computadores, na quarta geração,
qualquer pessoa passou a poder ter o seu.

Com o seu público-alvo mudando de foco, os sistemas operacionais


tiveram que se adaptar. O Minix (abreviação de mini-Unix), criado
no fim da terceira geração por Andrew Stuart Tanenbaum serviu de
inspiração para que um jovem estudante chamado Linus Torvalds criasse
seu próprio sistema operacional, o Linux. Sistema que acabou evoluindo
e se tornando um dos sistemas operacionais mais usados do mundo,
principalmente por usuários mais experientes.

De acordo com Tanenbaum (2010), paralelamente à evolução do


Linux, a IBM (International Business Machines) criou o seu primeiro
computador pessoal, chamado IBM PC, porém sem ainda ter um sistema
operacional para colocar nele. A IBM então entrou em contato com
um estudante de Harvard chamado Bill Gates, que havia criado alguns

www.esab.edu.br 20
programas para linguagens de programação, como Basic, para gerar uma
versão desses programas para o novo IBM PC. Como a IBM precisava de
um sistema operacional, perguntaram se Gates não poderia fornecê-lo.

Ainda de acordo com Tanenbaum (2010), uma empresa chamada Seattle


Computer Products possuía um sistema operacional chamado DOS –
Disk Operating System, ou Sistema Operacional de Disco. Bill Gates
então comprou essa empresa, realizou mudanças no sistema operacional,
criou sua própria empresa chamada Microsoft e relançou o DOS sob o
nome de MS-DOS, o qual foi usado pela IBM, não só no IBM PC como
também em seus produtos seguintes, como no IBM PC/AT.

Tanto o MS-DOS quanto o Linux continuaram crescendo, mas até 1984


os sistemas operacionais ainda possuíam apenas interfaces textuais, onde
o usuário se comunicava com o computador usando unicamente um
teclado. Para o novo público de usuários que não possuíam conhecimentos
avançados sobre o uso de computadores, isso era um problema.

Foi então que, de acordo com Tanenbaum (2010), em 1984, Steve


Jobs, um dos fundadores de uma empresa de computadores chamada
Apple, revolucionou a interação ao criar os primeiros computadores
com interface gráfica de usuário, o Apple Lisa e o Apple Macintosh,
que possuíam uma tela e um mouse, tecnologia nova desenvolvida
pela Xerox. Dessa forma, a Apple permitiu que até mesmo pessoas que
não sabiam e nem gostariam de saber nada sobre o funcionamento dos
computadores pudessem também usá-los para seu benefício.

A Microsoft de Bill Gates logo viu a revolução que o Macintosh estava


iniciando e criou também seu sistema operacional com interface gráfica,
o Microsoft Windows, em 1985.

Em termos de sistema operacional, o Macintosh foi criado com base no


Unix, enquanto o Windows foi inicialmente criado a partir do DOS. O
Macintosh apenas evoluiu ao longo dos anos (e mudou de nome para
OS X), mas sem grandes mudanças na sua estrutura, já o Windows da
Microsoft possuía diversas falhas e precisava de melhorias na sua estrutura.
Um novo sistema operacional foi então criado, chamado internamente
de Windows NT. O Windows NT, alguns anos depois, substituiu o

www.esab.edu.br 21
Windows antigo e foi lançado para o público geral sob o nome de
Windows XP, que veio a se tornar a versão de maior sucesso da linha de
sistemas operacionais da Microsoft e consolidou seu domínio do mercado.

Nos dias atuais os sistemas operacionais Windows, Macintosh (OS X)


e Linux mantêm praticamente a mesma base, ou kernel, que possuíam
anos atrás. O kernel de cada um desses sistemas não evoluiu tanto,
apenas pequenos ajustes foram (e ainda são) realizados.

A interface de apresentação do sistema operacional e o gerenciamento de


dispositivos de entrada e saída, porém, continuam evoluindo bastante.
Nos últimos anos, esses sistemas operacionais passaram por adaptações
e começaram a ser usados não só em computadores como também em
dispositivos menores e móveis, como celulares. As versões mais recentes
do Windows Phone foram criadas com base na plataforma Windows
NT da Microsoft, a mesma do Windows XP e seus sucessores. O iOS da
Apple foi criado com base no OS X, e o Android do Google foi criado
com base no Linux. Note que o desenvolvimento desses sistemas sempre
esteve muito relacionado ao desenvolvimento das próprias máquinas
sobre as quais eles executam, e por isso ao longo dos anos eles sofreram
tantas mudanças. A partir da próxima unidade iremos mergulhar
nos estudos desses sistemas, entendendo todos os aspectos do seu
funcionamento. Até lá!

Saiba mais
Como você viu nesta unidade, o mundo da
computação e dos sistemas operacionais que
usamos hoje não seria o mesmo sem o trabalho de
Bill Gates e Steve Jobs. Juntos eles não mudaram
apenas a computação, mudaram o mundo.
Assista ao vídeo disponível aqui para conferir um
documentário em que ambos discutem o passado,
o presente e suas visões a respeito do futuro da
computação.

www.esab.edu.br 22
4 Princípios de hardware e software
Objetivo
Conceituar os componentes de hardware e software de um
computador, possibilitando que o aluno contextualize o papel de um
sistema operacional.

Nas unidades anteriores estudamos um pouco da história dos sistemas


operacionais, desde os primeiros esboços até os sistemas atuais: Windows,
Linux e OS X. Vimos que esses sistemas são muito influenciados pelo
hardware sobre o qual eles são executados e que uma das funções desses
sistemas é justamente gerenciar os recursos desse hardware.

Por isso, nesta unidade, usando como base o trabalho de Tanenbaum


(2010), vamos ver os componentes de hardware de um computador e
ter uma noção melhor a respeito de quais são os recursos que o sistema
operacional precisa gerenciar. Por fim, vamos estudar um pouco sobre
as diferentes estruturas que os sistemas operacionais e os aplicativos
podem possuir.

Antes de começarmos, é importante notar que quando usarmos o termo


computador, estamos nos referindo não apenas aos computadores
pessoais (como computadores de mesa e notebooks), estamos também
nos referindo aos novos dispositivos móveis (como smartphones e
tablets). Isso porque o nível de desenvolvimento da tecnologia dentro
desses dispositivos já alcançou tal nível que eles podem ser tratados de
igual para igual se comparados aos computadores tradicionais.

Então, vamos começar estudando os componentes de hardware de um


computador para compreendermos melhor que tipos de recursos de
hardware o sistema operacional precisa gerenciar.

www.esab.edu.br 23
4.1 Componentes de hardware
O componente fundamental de hardware de um computador é o
processador, ou UPC. Como diz Tanenbaum (2010), ele é o cérebro do
computador. A UPC é a responsável por executar cada instrução de cada
programa do computador. Ao executar um programa de computador,
o responsável por isso será o processador. Ele também é responsável
por executar o código de todos os outros programas no computador,
inclusive do próprio sistema operacional.

Ser capaz de executar o código de todos os programas significa ser capaz


de compreender e executar qualquer comando da linguagem de máquina
do computador. Por essa razão, o processador é um componente bem
complexo. Para saber qual código executar, o processador lê cada
instrução do programa da memória, uma a uma, sempre escritas em
linguagem de máquina.

A memória é um componente de armazenamento, como um quadro


branco, que pode ser escrito e apagado diversas vezes. Quando o
processador deve executar uma instrução, algum componente do
computador deve dizer para ele: execute as instruções que estão em tal
local da memória. Então, o processador lê a memória na posição indicada
e começa a executar as instruções lá escritas.

De forma geral, podemos dizer que existem dois tipos de memória: as


memórias voláteis e as não voláteis. Uma memória volátil é aquela que
precisa de uma fonte de energia para manter os dados armazenados.
Se a fonte de energia for removida, todos os dados serão perdidos. Por
outro lado, uma memória não volátil mantém os dados armazenados
mesmo quando fica sem energia. Ou seja, podemos escrever dados nessa
memória, em seguida desligá-la, religá-la e os dados continuarão lá.

A princípio poderíamos dizer que as memórias não voláteis são melhores


e por isso deveríamos usar apenas elas. Porém, uma característica das
memórias não voláteis é que o tempo para ler ou escrever algum dado
nelas é muito mais alto do que o tempo para ler ou escrever em uma

www.esab.edu.br 24
memória volátil. Se utilizássemos apenas memórias não voláteis, o
processador iria gastar muito tempo lendo cada instrução da memória e a
execução dos programas seria muito mais lenta.

Assim, na prática, os computadores precisam ter pelo menos duas


memórias, uma volátil e uma não volátil.

A memória não volátil é o que chamamos comumente de disco rígido,


ou HD, do computador, ou também memória secundária. A memória
volátil é a memória principal, também chamada de memória RAM,
sigla em inglês para Random-Access Memory, ou Memória de Acesso
Aleatório. Um computador pode ter vários discos rígidos e várias
memórias RAM.

Todos os programas e dados do computador ficam armazenados na


memória secundária. Quando comunicamos para o sistema operacional
que queremos executar algum programa, ele pega as instruções desse
programa e os dados que ele usa e os copia para a memória RAM,
replicando-os.

Em seguida, o processador começa a executar as instruções do programa


lendo-as diretamente da memória RAM, que é volátil e possui leitura
e escrita mais rápidas. Quando o programa não for mais executado, o
sistema operacional o apaga da memória RAM. Se por acaso, em algum
momento, o computador for desligado, todo o conteúdo da memória
RAM é apagado, fazendo com que dados dos programas que estavam em
execução sejam perdidos.

Por exemplo, se estivermos executando um editor de texto e estivermos


digitando um texto, esse texto será tratado como dados do programa
e ficará guardado na memória RAM. Se o computador for desligado
inesperadamente, todo o texto que estávamos digitando será perdido.
Uma solução para esse problema seria o programa periodicamente
copiar o texto para o disco rígido, onde ele ficaria salvo caso o
computador fosse desligado.

www.esab.edu.br 25
Os computadores mais modernos (da quarta geração) não possuem
apenas essas duas memórias. Na prática, a memória principal costuma ser
dividida em várias camadas, geralmente três ou quatro, formando junto
com a memória secundária o que chamamos de hierarquia de memória. A
primeira camada, do ponto de vista da UPC, fica dentro da própria UPC,
que são os registradores. A quantidade de registradores é bem pequena,
assim como o tempo de acesso. As camadas seguintes são as camadas de
cache. Partindo dos registradores em direção à memória principal, temos
cada vez camadas de memória maiores, mais lentas e mais baratas.

Como nós, usuários, damos ordens ao próprio sistema operacional? E


onde vemos o resultado das computações feitas pelo processador? Os
componentes de hardware responsáveis por essas e mais funções são os
dispositivos de entrada e saída (E/S) do computador. Dispositivos comuns
de entrada de dados são mouse, teclado, superfícies touchscreen, microfone
etc., enquanto alguns possíveis dispositivos de saída são tela, impressão,
caixas de som etc. Também é preciso lembrar-se da rede, inclusive a
internet, que envia dados para o computador ou recebe dados enviados
pelo computador. Esses dispositivos se comunicam com o computador por
meio de várias interfaces diferentes, como antena wireless ou portas USB.

Para sua reflexão


Note que dentro do computador deve existir
uma forma de comunicação entre todos esses
dispositivos que mencionamos. Por exemplo,
como os dados são transportados da memória
principal para o processador ou da memória
secundária para a memória principal ou da
memória principal para a impressora? Além
disso, com que frequência precisamos transportar
esses dados e em que quantidade o fazemos?
Poderíamos usar o mesmo mecanismo de
comunicação para todos os tipos de dados que
transportamos entre os componentes de hardware
do computador?
A resposta a essa reflexão forma parte de sua
aprendizagem e é individual, não precisando ser
comunicada ou enviada aos tutores.

www.esab.edu.br 26
Dentro do computador deve existir uma forma de todos esses
componentes se comunicarem entre si. Para realizar essa função, existe
outro componente de hardware do computador chamado de barramento.

Chamamos de barramento todo meio de comunicação utilizado dentro de


um computador. Em termos gerais, são conjuntos de fios condutores de
energia elétrica por onde a informação é transportada. Em um computador
podem existir diversos barramentos diferentes, para diferentes funções.
Barramentos são classificados pelo que chamamos de largura de banda
ou bandwidth. A largura de banda de um barramento é a quantidade de
informação que ele consegue transmitir ao mesmo tempo, geralmente em
uma potência de dois (32 bits, 64 bits etc.) por segundo.

Como vimos anteriormente, esses componentes de hardware são


gerenciados pelo sistema operacional, porém o próprio sistema
operacional e os programas de usuário podem ser divididos em diferentes
componentes e podemos organizá-los de formas diferentes também,
como veremos a seguir.

4.2 Componentes de software


A UPC, conectada às memórias e aos dispositivos de E/S, forma a
estrutura do hardware do computador. Mas onde entra o software nessa
história? O software é a informação trocada por todos esses dispositivos.
É abstrato, ou seja, não pode ser tocado.

Existe um software responsável por gerenciar o uso de todos esses


recursos de hardware que vimos, é o sistema operacional, que nós
abreviaremos com SO. Quando ligamos o nosso computador, a
UPC começa imediatamente a funcionar e a executar instruções e a
primeira coisa que ela faz é executar um software que já vem dentro do
computador, chamado Bios, sigla em inglês para Basic Input/Output
System, ou Sistema Básico de Entrada/Saída. A Bios verifica se todos os
componentes de hardware estão presentes e conectados corretamente: em
caso positivo, ela pega as rotinas iniciais do SO na memória secundária,
carrega-as para a memória RAM e solicita à UPC que as execute. Daí em

www.esab.edu.br 27
diante o SO toma controle do computador, gerenciando os recursos de
hardware, aguardando comandos por parte do usuário e permitindo que
os programas do usuário sejam executados.

Depois de carregado, o SO exibe para o usuário a sua interface de


comunicação, geralmente gráfica, e fica esperando por comandos. Junto
com o SO, diversos outros softwares são executados em um computador,
vários deles até mesmo fazem parte ou se relacionam diretamente com
o SO. Os softwares em um computador se dividem, então, em modo
kernel ou modo usuário, como vimos na unidade 1.

A estrutura do SO pode variar muito. Um tipo de estrutura de SO é


o microkernel, ou micronúcleo. Nesse cenário, no modo kernel, no
qual o software possui total controle sobre o hardware, são executadas
apenas as rotinas mais importantes do SO, como o gerenciamento do
uso do processador e das memórias voláteis. Isso permite a existência
de um kernel mais robusto e eficiente, separando as funcionalidades
auxiliares do núcleo do SO. Essas outras funções ficam executando em
modo usuário, como se fossem programas do usuário. Isso inclui funções
como gerenciamento dos dispositivos de E/S e o gerenciamento do
disco rígido, também visto como sistema de arquivos. O Minix, criado
por Andrew Tanenbaum, é um exemplo de SO com microkernel. A
Figura 5 representa as diferentes estruturas de um Sistema Operacional:
microkernel, kernel monolítico e kernel híbrido. Veja:

www.esab.edu.br 28
Microkernel Kernel monolítico Kernel híbrido

Modo usuário
Modo kernel
programas do usuário funções auxiliares do SO
funções essenciais do SO, como gerenciamento dos processos
Figura 5 – Diferentes estruturas de um SO: microkernel, kernel monolítico e kernel híbrido.
Fonte: Elaborada pelo autor (2013).

A Figura 5 ilustra os três tipos de estrutura de SO que estamos vendo.


A estrutura mais à esquerda mostra o microkernel. Veja que apenas
as funções mais essenciais do SO executam em modo kernel. Outro
tipo de estrutura de SO é o tipo kernel monolítico. Nesse cenário,
todas as funções do SO fazem parte do kernel e executam em modo
kernel, inclusive o gerenciamento dos dispositivos de E/S, o sistema de
arquivos e as funções de sistema que programas de usuário usam para se
comunicar com o SO e com o hardware. O Linux, o Android e o antigo
Windows (Windows 95, 98 e ME) são exemplos de sistemas operacionais
monolíticos. Veja na Figura 5, na estrutura do meio, que apenas os
programas de usuário estão sendo executados em modo usuário.

Por fim, existe o tipo de kernel híbrido, que une conceitos de kernel
monolítico e microkernel. Em um kernel híbrido, algumas das funções
auxiliares do SO são executadas no modo kernel junto com as funções
básicas e essenciais, enquanto outras funções auxiliares são realizadas
em modo usuário, como é possível notar na estrutura mais à direita da
Figura 5. O gerenciamento dos dispositivos de E/S pode, por exemplo,
ser executado em modo kernel, enquanto o gerenciamento do sistema de
arquivos não. O OS X e a arquitetura Windows NT (Windows XP em
diante) são exemplos de sistemas operacionais de kernel híbrido.

www.esab.edu.br 29
Agora você já conhece os princípios de hardware e software de um
computador. Nas próximas unidades vamos começar a nos aprofundar
um pouco mais no funcionamento de um SO. Continue conosco!

www.esab.edu.br 30
Conceitos de um sistema
5 operacional – parte 1
Objetivo
Apresentar os componentes principais de um sistema operacional,
como processos e gerenciamento de memória.

Na unidade anterior estudamos os princípios de hardware e software


de um computador. Vimos de forma geral quais os componentes de
hardware de um computador e como eles interagem entre si. Vimos
também que o software do computador fica dividido em modo kernel
e modo usuário e que, dependendo do tipo de kernel do SO, as
funcionalidades do SO podem ser executadas todas em modo kernel ou
apenas as principais em modo kernel e as auxiliares em modo usuário.

Vimos até agora na disciplina que o sistema operacional abstrai o acesso


à memória secundária (disco rígido), permitindo que organizemos nossos
programas e dados de forma mais fácil. Abstrair, nesse caso, significa pegar
um conceito complexo e transformá-lo em um conceito menor, simples,
mais fácil de usar ou entender. Podemos assim solicitar a execução de um
programa específico. O sistema operacional então transfere o programa
da memória secundária para a memória principal (RAM), interrompe
o que a UPC está fazendo e informa à UPC as instruções do programa
que ele deve executar. Se o programa envia dados para a internet ou
recebe comandos do usuário através de um mouse, é o SO que gerencia e
organiza essa comunicação, de forma que nem o programa e nem o usuário
precisam se preocupar com a forma com que é feita essa comunicação,
ou seja, a comunicação é transparente. Dessa forma, nunca precisamos
nos preocupar com o funcionamento da UPC, das memórias ou dos
dispositivos de E/S, pois o SO cuida de tudo isso para nós.

Com base no trabalho de Tanenbaum (2010) e Silberschatz, Galvin


e Gagne (2001), nesta unidade e na próxima vamos começar a nos
aprofundar um pouco no funcionamento de um SO. Por causa da alta
complexidade do SO, vamos apenas introduzir, nestas unidades, quais

www.esab.edu.br 31
componentes fazem parte dele, para então nas unidades seguintes começar
a estudá-los um a um. Vamos iniciar estudando o que são processos,
conceito fundamental para a execução de programas de computador.

5.1 Processos
Quando o programa está armazenado na memória secundária, sem ser
executado, ele não passa de um pedaço de texto, composto por diversas
instruções, que formam o código do programa, e vários dados que o
programa precisa quando é executado. O sistema operacional conhece e
gerencia a execução de todos os programas no computador, inclusive ele
mesmo. Então quando esse programa passa a ser executado, o SO reúne
várias informações novas a respeito do programa e cria uma estrutura
maior, usada para gerenciar sua execução.

Essa estrutura maior que representa o programa é chamada de processo.


Ou seja, de acordo com Silberschatz, Galvin e Gagne (2001), processo
é como chamamos um programa em execução. Quando começamos
a executar um programa, um processo é criado para ele, o qual guarda
todas as informações referentes ao programa. Quando finalizamos o
programa, o processo é finalizado.

Esse processo nada mais é do que um conjunto de informações na


memória principal, as quais são de conhecimento do SO e gerenciadas
por ele. Nesse conjunto de informações na memória, está todo o código
do programa em execução, todos os dados que ele possui e também algo
que chamamos de a pilha do processo, que será estudada em detalhes
mais à frente.

Além disso, é guardado também um grupo de informações a respeito


do estado atual de execução do processo. Esse grupo de informações é
útil especialmente em cenários de multiprogramação. Hoje em dia, a
maioria dos computadores possui UPCs com um, dois, quatro ou até
oito núcleos (ou cores). De forma geral, isso significa que o computador
consegue executar até oito programas (processos) simultaneamente.
Porém, nos computadores modernos é fácil encontrarmos dezenas ou

www.esab.edu.br 32
centenas de processos abertos e executando ao mesmo tempo. Como
esses processos são executados se a UPC só consegue executar até oito
processos ao mesmo tempo?

O que o SO faz é de tempos em tempos interromper a execução do


processo atual e permitir que outro processo seja um pouco executado.
Quando for a vez de executar o processo prévio novamente, sua execução
precisa reiniciar exatamente de onde parou, como se ele nunca tivesse
parado de executar. Para isso, todas as informações referentes ao estado
atual de execução do processo precisam ficar guardadas para que, quando
voltar a executar, o SO saiba exatamente onde ele parou. Uma dessas
informações é o contador do programa, ou program counter. Esse
contador informa ao SO em qual instrução o processo está. Por exemplo,
se o processo tiver executado a instrução 500 e for interrompido, quando
ele puder voltar a executar, verá no contador do programa que a execução
foi parada na instrução 500 e continuará a execução na instrução 501.

Cada processo também armazena algumas listas de informações úteis. Por


exemplo, cada processo tem uma lista de arquivos do computador que ele
abriu e está lendo ou manipulando, uma lista de outros processos que se
comunicam com ele, outras listas de recursos do SO e do hardware que o
processo está usando.

É comum que um programa em execução queira iniciar a execução


de outro programa, e por isso é possível que processos criem novos
processos, chamados processos filhos. Esses processos podem ainda criar
outros processos e assim por diante. Na verdade, a estrutura usada pelo
SO para gerenciar todos os processos do computador assume a forma
de uma árvore. Estudaremos em mais detalhes o conceito de processos a
partir da unidade 7, mas uma coisa que todo processo possui e utiliza é
um espaço de endereçamento, como veremos a seguir.

www.esab.edu.br 33
5.2 Espaços de endereçamento
Como comentamos anteriormente, os processos do computador residem
na memória principal. Quando nos referimos, em unidades anteriores,
que na execução de um programa o código e dados deste são copiados
da memória secundária para a memória principal, estávamos falando
da criação de processos. Essa memória principal armazena todo o
código e todos os dados de todos os programas em execução e é o único
fator que limita a quantidade de programas que podem ser executados
simultaneamente em um computador.

De acordo com Tanenbaum (2010), é na memória que estão localizados


todos os processos, e o local na memória onde cada processo fica
armazenado é chamado de espaço de endereçamento. Chamamos
de espaço de endereçamento porque cada espaço da memória onde
algum dado pode ser colocado é chamado de endereço, e o conjunto de
endereços disponível para ser ocupado por um processo é o seu espaço
de endereçamento. Esse espaço pode aumentar conforme as necessidades
do programa.

É essencial que um processo jamais consiga acessar endereços de


memória que pertencem a outros processos, pois isso permitiria que um
processo possivelmente descobrisse informações confidenciais de outro
processo. Por exemplo, um programa usado para acessar uma conta
em um banco poderia guardar dados dessa conta na memória e então
outro programa malicioso poderia facilmente acessá-las e, dessa maneira,
roubar dados do usuário.

Tentar burlar esse bloqueio de acesso da memória é na verdade uma


das maiores fontes de softwares maliciosos, como vírus de computador.
O SO é o responsável por impedir que isso aconteça, através de um
complexo gerenciamento de memória que estudaremos com mais
detalhes a partir da unidade 13.

www.esab.edu.br 34
Saiba mais
Além da fonte de softwares maliciosos que
comentamos anteriormente, existem diversas
outras fragilidades nos computadores que
permitem que programas estranhos acessem
ou modifiquem informações que não deveriam,
geralmente por essas informações não estarem
seguras o suficiente ou porque o sistema
operacional não realizou corretamente a função de
protegê-las. Para saber mais sobre vírus e outros
softwares maliciosos, assista ao vídeo
disponível aqui.

Você acabou de estudar dois conceitos muito importantes para o


estudo de sistemas operacionais: o conceito de processo e o de espaço
de endereçamento. Na próxima unidade continuaremos introduzindo
alguns conceitos importantes, antes de nos aprofundarmos no estudo de
processos na unidade 7.

www.esab.edu.br 35
Conceitos de um sistema
6 operacional – parte 2
Objetivo
Apresentar outros conceitos presentes em um sistema operacional,
como gerenciamento de arquivos, dispositivos de entrada e saída e
interfaces de comunicação com aplicações.

Na unidade anterior começamos a introduzir alguns conceitos


importantes a respeito de sistemas operacionais, que ilustram melhor a
estrutura do sistema.

Vimos que processos são programas em execução, e uma boa parte das
funções do SO é gerenciar a execução de todos os processos. Se algum
processo quer usar algum recurso de hardware, o SO fornece o recurso;
se o processo quer iniciar outro processo, o SO cuida de buscá-lo da
memória secundária, criar um espaço na memória principal para ele, e
gerenciar esse uso da memória de forma transparente até mesmo para o
processo em execução.

Além disso, com tantos processos no computador e poucos núcleos


de processamento, a própria UPC se torna um recurso que precisa
ser gerenciado para que todos os processos consigam ser executados
normalmente. Essas duas grandes funções do SO serão discutidas em
mais detalhes da unidade 7 até a 12.

Também vimos na unidade anterior que a memória principal é usada


para armazenar esses processos e que cada um deles possui um espaço de
endereçamento próprio, fora do alcance dos outros, onde todo o código
e os dados do processo ficam organizados. O gerenciamento da memória
também é uma das funções do SO e será melhor estudado da unidade
13 até a 18.

www.esab.edu.br 36
Agora, usando como base o trabalho de Tanenbaum (2010), vamos
introduzir outros conceitos importantes para o estudo de sistemas
operacionais, como arquivos, dispositivos de entrada e saída, entre outros.

6.1 Arquivos
Semelhante ao gerenciamento da memória e dos espaços de
endereçamento, o SO também precisa gerenciar a memória secundária
ou os dispositivos de memória não volátil de modo geral. Se um
programa na memória principal ocupa um espaço de endereçamento
e é chamado de processo, quando ele está na memória secundária
ele é um conjunto de arquivos e diretórios. O conjunto de todos os
diretórios e arquivos da memória secundária junto com algumas diretivas
de estruturação desses dados forma o que chamamos de o sistema de
arquivos do computador.

A estrutura de um sistema de arquivos também assume a forma de uma


árvore, assim como a estrutura dos processos. A Figura 6 ilustra uma
possível configuração do sistema de arquivos do sistema operacional
Windows com alguns diretórios, também chamados pastas, comuns do
sistema.

C:\

Arquivos de programas Usuários Windows

Maria Mateus

Músicas Vídeos

Figura 6 – Exemplo de parte do sistema de arquivos do sistema operacional Windows.


Fonte: Elaborada pelo autor (2013).

www.esab.edu.br 37
Veja que a estrutura lembra a forma de uma árvore, por isso chamamos
de estrutura de árvore. No nível superior está a raiz da árvore, que no
Windows costuma ser chamada de C:\ e no Linux é chamada apenas de
\. Os diretórios permitem que os arquivos sejam organizados conforme
a vontade do usuário. Cada arquivo ou diretório no computador possui
um caminho de arquivo que o identifica. Esse caminho é formado pelo
nome de cada diretório no caminho, separado por uma barra invertida
\ (no Linux usa-se uma barra normal /). Por exemplo, o caminho
do diretório Músicas da Figura 6 é C:\Usuários\Maria\Músicas. Esse
caminho é como um valor de identificação de cada arquivo ou diretório e
é único para cada um.

Embora de forma abstrata, os arquivos e diretórios do computador ficam


organizados nessa estrutura de árvore chamada sistemas de arquivos,
dentro da memória secundária em si os arquivos ficam em lugares
aleatórios, desconhecidos por parte dos usuários, que só o sistema
operacional sabe. O SO abstrai totalmente o espaço de armazenamento
não volátil do computador, permitindo que todos os arquivos façam
parte do sistema de arquivos.

Boa parte dos arquivos no computador são apenas dados, como músicas,
vídeos e documentos. Esses dados podem ser lidos ou sobrescritos por
programas de computador, conforme as autorizações do usuário. Sempre
que o usuário tenta abrir um arquivo do computador, um processo
é iniciado. Se o arquivo é uma música, é criado um processo para o
programa padrão de reprodução de músicas e ele é executado. Se o
arquivo for um programa propriamente dito, é criado um processo para
permitir a execução desse programa.

Os sistemas de arquivos e o gerenciamento de arquivos em geral serão


tratados com mais detalhes nas unidades 19 e 20.

www.esab.edu.br 38
6.2 Entrada e saída
Como já comentamos, o computador possui UPC, memória principal,
memória secundária e diversos dispositivos de E/S, também chamados
de periféricos, todos conectados por barramentos. Conforme afirma
Tanenbaum (2010), o SO é também o responsável por gerenciar a
comunicação de todos esses dispositivos com o processador e a memória,
possuindo então um sistema de gerenciamento de dispositivos de entrada
e saída.

Esse sistema abstrai a forma como todos esses dispositivos se comunicam


com o computador. Geralmente cada dispositivo possui sua interface
de comunicação, que costuma ser muito pouco abstrata. Ou seja, o
software que se comunicar com o dispositivo precisa saber detalhes
bastante específicos a respeito de como opera o dispositivo. Além disso,
vários detalhes de funcionamento não são tratados pelo dispositivo.
Por exemplo, dados entrando no computador através de uma rede são
apenas bytes de dados, que às vezes vêm repetidos, às vezes chegam na
ordem errada etc. O dispositivo de rede não cuida de organizá-los. Outro
exemplo de dispositivo bastante diferente, mas igualmente complexo, são
os monitores. Um monitor é geralmente conectado ao computador por
meio de uma sequência de pinos seriais. Cada pino possui uma função,
e dados trafegam por esses pinos em direção ao monitor de forma bem
específica, porém pouco clara e nada abstrata.

Programas de computador não precisam se preocupar com a interface


de comunicação dos monitores ou dos teclados ou mesmo superfícies
touchscreen. Também não precisam se preocupar com a organização
dos dados que trafegam na rede e suas interferências inerentes.
O sistema operacional gerencia todos esses recursos, embora esse
gerenciamento algumas vezes cause problemas, como será visto melhor
nas unidades 21 e 22.

www.esab.edu.br 39
6.3 Outros componentes
Um sistema operacional também possui diversos outros componentes
além desses que introduzimos nas últimas duas unidades. Esses
componentes, porém, costumam apenas complementar o conjunto de
funções do SO, sem serem peças fundamentais dele.

Novamente, conforme afirma Tanenbaum (2010), outra estrutura, além


das que já comentamos, é a interface de comunicação com as aplicações,
também chamada de API do sistema operacional. Ela consiste em um
grupo de funções e rotinas que programas de usuário podem chamar para
utilizar funções do SO ou recursos de hardware. Através dessa API, é
possível, por exemplo, criar ou remover arquivos, iniciar processos, enviar
dados pela internet, entre outras funções permitidas para programas que
executam em modo usuário.

Embora tenhamos passado as últimas duas unidades listando diversos


componentes de um sistema operacional, ainda estamos longe de
descrever tudo o que ele realiza. Ao longo das próximas unidades,
vamos nos focar naqueles tópicos fundamentais e mais importantes,
e trataremos superficialmente daqueles assuntos que apenas
complementam o conhecimento do aluno. Na próxima unidade, vamos
mergulhar no estudo dos fundamentos dos sistemas operacionais,
conhecendo melhor o que são processos e como eles são gerenciados.

Fórum
Caro estudante, dirija-se ao Ambiente Virtual de
Aprendizagem da instituição e participe do nosso
Fórum de discussão. Lá você poderá interagir com
seus colegas e com seu tutor de forma a ampliar,
por meio da interação, a construção do seu
conhecimento. Vamos lá?

www.esab.edu.br 40
Resumo

Nas seis primeiras unidades desta disciplina começamos o estudo


de sistemas operacionais. Vimos inicialmente o que são sistemas
operacionais e pudemos entender um pouco melhor os motivos de eles
serem tão complexos.

Estudamos também um pouco da história dos sistemas operacionais


desde a primeira geração de máquinas pensadas como estratégia militar
na Segunda Guerra Mundial até os sistemas operacionais mais recentes,
como o OS X e o Android.

Além disso, introduzimos princípios de hardware e software do


computador, conceitos que serão muito úteis ao longo da disciplina.
Estudamos também quais componentes de hardware um computador
possui e que tipos de software executam sobre esse hardware. Por fim,
estudamos os conceitos básicos de um sistema operacional, como
processos, espaços de endereçamento, sistemas de arquivos etc., abrindo
caminho para um estudo mais aprofundado desses fundamentos a partir
das próximas unidades.

www.esab.edu.br 41
7 Introdução a processos
Objetivo
Introduzir o conceito de processo, apresentando o modelo de um
processo e seu comportamento em um sistema computacional.

Nas primeiras seis unidades de estudo da disciplina introduzimos o


conceito de Sistema Operacional (SO) e vimos um pouco da história e
evolução desses sistemas. Estudamos também os princípios de hardware
e software que formam a base para os SOs e também quais estruturas
básicas compõem um SO.

A partir desta unidade até a unidade 12, estudaremos a principal


função dos SOs: o gerenciamento de processos. Nesta unidade,
fundamentaremos nossos estudos em Silberschatz, Galvin e Gagne
(2001) e Tanenbaum (2010). Este último afirma que a noção de
processos é o principal conceito no estudo de sistemas operacionais, e
que todo aluno de SOs deve compreender esse conceito o mais cedo
possível. Então, vamos começar logo a estudar a fundo esse conceito tão
importante!

7.1 O que é um processo?


De acordo com Silberschatz, Galvin e Gagne (2001) e Tanenbaum
(2010), um processo é um programa em execução. Como vimos
nas primeiras unidades de estudo desta disciplina, os programas de
computador são formados por diversas linhas de código e mais um
conjunto de dados que são usados pelo programa. Essas linhas de código
e dados são apenas informações digitais e ficam armazenadas na memória
secundária do computador.

www.esab.edu.br 42
Quando solicitamos ao SO que execute um programa, o código e os
dados do programa são copiados para a memória principal, criando
uma instância “viva” do programa, e o processador começa a executar
cada uma das suas instruções. A partir desse momento, essa instância do
programa sendo executada pelo processador é chamada de processo, por
isso dizemos que um processo é como chamamos um programa quando
ele está em execução.

Para gerenciar a execução do processo, o SO precisa de algumas


informações a respeito das atividades do processo e essas informações
são guardadas junto com o processo, na memória principal. Uma dessas
informações úteis é o contador do programa, ou program counter, que
é um dado que informa ao processador qual é a próxima instrução do
programa que ele deverá executar. Estudaremos mais sobre o contador
do programa e outros conceitos importantes ao longo das próximas
unidades. A Figura 7 ilustra a criação do processo, como descrito
previamente.

Processo ocupando espaço Programa armanezado na


na memória principal memória secundária
...
#include <stdio.h> ...
int main(void) Código
(
#include <stdio.h>
printf(”Teste”);
int main(void)
} (

printf(”Teste”);
Dados
}
Fluxo de execução
Contador do programa Dados
...
Outras informações ...
...
Memória principal Memória secundária
Figura 7 – Criação de um processo no qual seu código e seus dados são copiados e uma estrutura de
gerenciamento do processo é criada na memória principal.
Fonte: Elaborada pelo autor (2013).

www.esab.edu.br 43
À direita temos o código e os dados do programa sendo armazenados
na memória secundária e à esquerda temos esse mesmo programa em
execução, já tratado como processo. Veja que o processo possui uma área
chamada de fluxo de execução. O fluxo de execução de um processo
possui informações a respeito da execução do processo, por exemplo, o
contador do programa, que acabamos de descrever.

Dessa forma, já sabemos como o processo é armazenado e onde ficam


seus dados. Mas o que acontece com ele quando ocupa a memória
principal? Como seu código é executado? Para que servem esses dados de
fluxo de execução? Veremos isso a seguir.

7.2 Comportamento básico de um processo


Da mesma forma como ocorre para o programa usado como exemplo
na Figura 7, todos os outros programas executados no computador
também são carregados para a memória principal e tratados como um
processo pelo SO durante a sua execução. E, como sabemos, todos
os computadores modernos são multiprogramados, ou seja, diversos
programas costumam estar em execução ao mesmo tempo. Uma boa
forma de notar isso na prática é executando a ferramenta Gerenciador de
Tarefas, disponível no SO Windows, que mostra todos os processos em
execução nesse momento no computador (geralmente disponível através
do atalho Ctrl + Alt + Del).

O SO é o responsável por gerenciar todos esses processos criados e em


execução. Para realizar isso, o SO possui uma estrutura em forma de
árvore que contém todos os processos do computador, como vemos na
Figura 8. Cada processo possui um processo-pai, o qual o criou, assim,
como cada processo pode ter um ou mais processos-filhos criados por ele.

www.esab.edu.br 44
Processos do Sistema Operacional

Processo 1 Processo 2 Processo 3

Processo-filho 1 Processo-filho 2
Figura 8 – Estrutura de gerenciamento dos processos do computador.
Fonte: Elaborada pelo autor (2013).

Após o processo ser criado na memória principal e fazer parte do


grupo de processos que já estavam lá, é hora de suas instruções serem
executadas. Isso, como já vimos anteriormente, é função do processador.
O SO é responsável primeiramente por informar ao processador as
informações do fluxo de execução do processo. Por exemplo, ele informa
em qual local da memória está a primeira instrução do programa.
De posse dessas informações, o processador começa a executar todas
as instruções, uma a uma, até que o próprio SO intervenha e diga o
contrário.

Porém, o processador só consegue executar um processo de cada vez.


Então, como o SO faz para que todos os processos em execução tenham
suas instruções executadas? Antes de explicarmos como funciona esse
mecanismo, note que os processadores atuais possuem, geralmente, mais
de um núcleo de processamento, alguns até mesmo possuem quatro,
oito ou mais. Isso significa que eles conseguem executar tantos processos
ao mesmo tempo quanto a quantidade de núcleos que possuem.
Porém, para simplificar nossos estudos, consideraremos nesta e nas
próximas unidades apenas processadores com um único núcleo. A base
é a mesma para todos, o conceito fica mais simples de compreender
se considerarmos apenas um núcleo. Dessa forma, um processador só
executa um processo de cada vez.

www.esab.edu.br 45
É nesse momento que entra uma das principais funcionalidades de
um SO, tão antiga quanto o próprio conceito de multiprogramação:
o gerenciamento da execução de todos os processos. Para permitir
que vários processos sejam executados e dar a impressão ao usuário de
que todos os processos estão sendo executados ao mesmo tempo, o que
o SO faz é permitir que o processador faça um rodízio de processos,
executando cada processo por um curto período de tempo, geralmente
alguns milissegundos, e então começando a executar as instruções de
outro processo por alguns milissegundos, depois de outro e assim por
diante até voltar a executar as instruções do primeiro. A Figura 9 ilustra
esse compartilhamento do tempo do processador por parte dos processos.

D
C
Processo

B
A

Tempo
Figura 9 – Uso do processador mostrado ao longo do tempo, em que somente um processo está ativo a cada
momento.
Fonte: Adaptada de Tanenbaum (2010).

A Figura 9 mostra que, a cada momento, um único processo é executado


pelo processador. As curtas linhas horizontais pretas mostram que,
naquele determinado momento, aquele processo estava em execução.
Por exemplo, destacamos três momentos distintos, mostrados nas retas
coloridas verticais. No primeiro destaque, em cor laranja, podemos ver
que o processo A está em execução, enquanto os processos B, C e D
estão aguardando. No segundo momento, destacado em cor verde, o
processo B está em execução, enquanto os outros aguardam. O momento
destacado em cor azul, porém, mostra o exato momento em que o SO
interrompe a execução do processo C e inicia a execução do processo D.

www.esab.edu.br 46
Dessa forma, todos os processos aparentam ser executados ao mesmo
tempo, embora a cada momento apenas um seja executado. Esse tipo de
execução também é chamado de pseudoparalela. Ou seja, a execução dos
processos aparenta ser realizada de forma paralela, mas na verdade não é.

Terminamos assim esta unidade sobre processos e seu comportamento.

Como vimos, é tarefa do SO gerenciar a execução dos processos de


forma eficiente o bastante para que o usuário tenha a impressão de
que realmente todos os processos estão em execução ao mesmo tempo.
Estudaremos isso detalhadamente a partir das próximas unidades e
também conheceremos mais aspectos dos processos.

Para sua reflexão


Vimos, nessa unidade, que o gerenciamento
dos processos realizado pelo SO permite que
todos os processos sejam executados aos poucos,
um de cada vez, em um revezamento, dando a
impressão de que todos estão executando ao
mesmo tempo. Chamamos essa execução dos
processos de pseudoparalela. Você consegue notar
esse gerenciamento ocorrendo no seu dia a dia?
Quando você está usando seu computador pessoal,
muitas vezes, você possui vários programas sendo
executados ao mesmo tempo, como um editor
de textos, um navegador web etc. Você consegue
notar a relação entre a execução desses programas
e a execução pseudoparalela que estudamos nessa
unidade?
A resposta a essa reflexão forma parte de sua
aprendizagem e é individual, não precisando ser
comunicada ou enviada aos tutores.

www.esab.edu.br 47
Gerenciamento de processos –
8 parte 1
Objetivo
Apresentar os estados possíveis de um processo e definir o conceito
de contexto de um processo.

Na unidade anterior iniciamos nosso estudo nos aprofundado a respeito


de processos. Vimos que quando executamos um programa, uma cópia
ou instância dele é criada na memória principal. Essa instância é tratada
como um processo, e sua execução é gerenciada pelo SO. Essa instância
do programa em execução não é simplesmente um texto formado por
um conjunto de instruções e dados.

Quando um processo está sendo executado, diversas informações a


respeito das atividades que ele exerce precisam ser guardadas para serem
usadas no gerenciamento do processo.

Vimos também que as instruções do processo são executadas pelo


processador, assim como também são executadas as instruções dos outros
processos. Vimos então que o SO permite que cada processo execute
por curtos períodos de tempo e então permita que os outros processos
executem. Todos os processos fazem parte desse rodízio.

Podemos compreender melhor esses conceitos utilizando a analogia de


um cozinheiro que deseja fazer vários pratos para o jantar. Os programas
guardados na memória secundária são como receitas de pratos, e os dados
que eles usam são os ingredientes. Nesse caso, o cozinheiro representa
a execução da receita. Ele pega cada receita e segue suas instruções,
preparando o prato. Em um segundo momento, o cozinheiro inicia o
preparo de outro prato, como se fosse o sistema operacional criando um
novo processo. Assim, o cozinheiro divide seu tempo preparando dois ou
mais pratos. O cozinheiro só consegue trabalhar em um prato de cada
vez, porém todos os pratos são feitos em conjunto.

www.esab.edu.br 48
No entanto, os possíveis estados de um processo não são simplesmente
ser criado, executar suas instruções quando o SO permitir e, então,
ser finalizado. Valendo-nos de Tanenbaum (2010), Deitel, Deitel e
Steinbuhler (2005) e, principalmente, Silberschatz, Galvin e Gagne
(2001), nesta unidade vamos estudar os principais estados possíveis
de execução de um processo. Também abordaremos o contexto de um
processo, ou seja, quais são essas informações que o SO guarda a respeito
do processo para auxiliá-lo no gerenciamento. Primeiro, veremos quais
são os estados de um processo.

8.1 Estados de processos


A Figura 10 mostra alguns estados possíveis para um processo e também
enumera as possíveis transições entre os estados. A forma como o
gerenciamento dos processos é implementado varia bastante de sistema
operacional para sistema operacional, mas o conceito de todos esses
estados está presente em todas as implementações.

Memória secundária

Programa
Salva dados do programa,
se existirem
Criação do processo Esperando
5

Criado 1 Pronto 4 Finalizando


3

2
6
Executando

Lê instrução, executa e
Processador
acessa dados do programa

Figura 10 – Estados e transições possíveis para processos em execução em um computador.


Fonte: Elaborada pelo autor (2013).

www.esab.edu.br 49
O primeiro estágio na vida de um processo é a criação, mostrado pelo
estado Criado. Veja que o SO primeiro pega o programa na memória
secundária e cria uma cópia dele na memória principal, a qual chamamos
de instância do programa, ou processo. Junto com a criação do processo,
as diversas informações úteis a seu respeito são inicializadas, permitindo
que ele se insira na estrutura de execução dos processos.

De acordo com Silberschatz, Galvin e Gagne (2001), ocorre a transição


1, chamada admissão, na qual uma estrutura chamada bloco de controle
do processo (PCB, do inglês process control block) é criada para o
processo e armazenada internamente pelo SO em uma estrutura que
Tanenbaum (2010) chama de tabela de processos. Ainda de acordo com
Tanenbaum (2010), esse PCB é responsável por guardar as informações
do fluxo de execução vistas na unidade anterior, por exemplo, o contador
do programa. Existem outras informações que esse PCB guarda e aos
poucos, ao longo da disciplina, as conheceremos melhor.

Após a criação do PCB, o processo passa para o estado Pronto e já pode


ser executado. Geralmente os SOs mantém uma fila de processos no
estado Pronto. Essa fila é como uma fila de espera, na qual os processos
ficam esperando para poderem ser executados. Quando chega a vez de
um processo ser executado o SO o transfere para o estado Executando,
ocorrendo então a transição 2.

A transição 2 ocorre sempre que o SO interrompe a execução de um


processo e dá espaço para outro executar. Essa interrupção do processo
por parte do SO para permitir que outro execute ocasiona a transição
3, em que o processo que estava em execução sai desse estado e vai para
o estado Pronto, fazendo parte da fila de processos naquele estado. A
decisão de qual processo vai executar em qual momento é chamada de
escalonamento, e o SO possui uma ferramenta chamada escalonador,
que realiza essa função. Estudaremos em detalhes esse escalonamento nas
próximas unidades.

Esse fluxo não é o único que existe. Durante a execução do código


do programa, pode ocorrer de o processo precisar esperar por dados
externos, como comandos do usuário ou dados vindo pela rede. Por
exemplo, se criamos um programa de uma calculadora, o processo deve

www.esab.edu.br 50
esperar por alguns segundos enquanto o usuário digita os valores e a
operação que deseja realizar com eles. Programas que se comunicam
em rede com outros programas também precisam, de vez em quando,
esperar que respostas cheguem pela rede. Nesses momentos, o processo
não possui instruções para executar no processador. Quando o processo
deseja esperar por alguma resposta do usuário ou da rede, ele próprio
pausa sua execução. Então, a transição 4 ocorre e o processo passa para o
estado Esperando. Assim, caso haja algum processo que esteja no estado
Pronto, o SO o pega e o passa para o estado Executando, substituindo o
processo que estava lá.

O processo permanece no estado Esperando enquanto a condição que


bloqueia sua execução não for resolvida – seja com a chegada de dados
pela rede, seja através de alguma ação do usuário. Quando isso ocorre,
o processo não volta a executar imediatamente, e sim vai para o estado
Pronto, ocasionando, novamente, a transição 5. Estando no estado
Pronto, o processo espera o SO informar que novamente é sua vez de ser
executado, retornando, então, ao estado Executando.

Na próxima unidade estudaremos em detalhes a criação e finalização


de processos. De forma resumida, a finalização do processo pode
ocorrer de várias formas, porém a mais comum delas ocorre quando
o próprio processo termina de realizar suas computações e efetua seu
próprio término. Nesse momento, ele sai do estado Executando e vai
para o estado Finalizado, ocasionando a transição 6, no qual o PCB
do processo é removido. A seguir, vamos estudar o que é o contexto de
processos.

8.2 Contexto de processos


A substituição de um processo em execução, realizada pelo SO toda vez
que algum processo sai do estado Executando e outro é colocado nesse
mesmo estado para substituí-lo, não é uma operação trivial. Para que
a execução do processo que está sendo interrompido possa continuar
exatamente de onde parou posteriormente, todas as informações atuais a
respeito do processo precisam ser guardadas.

www.esab.edu.br 51
Essa troca de processos é chamada de troca de contexto. De acordo com
Tanenbaum (2010) e Deitel, Deitel e Steinbuhler (2005), o contexto
de um processo consiste em todas as informações a respeito do processo
que o SO gerencia. Como vimos, essas informações ficam em uma tabela
de processos do SO, em uma estrutura chamada de PCB. De acordo com
Silberschatz, Galvin e Gagne (2001), esse PCB guarda informações como
o estado do processo, o número de identificação do processo, o contador
do programa, um grupo de registradores, os limites da memória alocada
para o processo, a lista de arquivos abertos pelo processo, entre outras.

Quando o processo está no estado Executando, os registradores do


processador (aqueles vistos na unidade 4) guardam informações
muito importantes e essenciais para a execução do processo. Como
os registradores são a forma de memória mais rápida do computador,
é essencial que esses dados importantes e muito usados fiquem em
registradores. Quando o processo é interrompido e ocorre uma troca de
contexto, o contexto atual do processo – ou seja, as informações que ele
precisa para ser executado – são salvas no PCB do processo, e o contexto
do próximo processo a executar é carregado para os registradores do
processador. Quando estudarmos o gerenciamento de memória e
gerenciamento de arquivos, entenderemos melhor o que são esses limites
da memória alocada para o processo e a lista de arquivos abertos por ele.

Na próxima unidade continuaremos apresentando os processos e estudando


em detalhes como o SO realiza a criação e o término de processos.

Atividade
Chegou a hora de você testar seus conhecimentos
em relação às unidades 1 a 8. Para isso, dirija-se
ao Ambiente Virtual de Aprendizagem (AVA) e
responda às questões. Além de revisar o conteúdo,
você estará se preparando para a prova. Bom
trabalho!

www.esab.edu.br 52
Gerenciamento de processos –
9 parte 2
Objetivo
Apresentar mecanismos de criação e término de processos.

Na última unidade começamos a estudar detalhadamente o


gerenciamento de processos realizado pelo SO. Já sabemos que um
processo é como chamamos o programa quando está sendo executado
e que para gerenciar sua execução, o SO mantém, internamente, uma
estrutura chamada PCB, única para cada processo. Nela, o SO armazena
diversas informações úteis a respeito do processo, e esse conjunto de
informações forma o que chamamos de contexto do processo.

Vimos também que o SO gerencia a execução de todos os processos.


Por meio de uma operação chamada escalonamento (que será estudada
nas próximas unidades), o SO controla qual processo será executado e
por quanto tempo, realizando um rodízio e permitindo que todos sejam
executados aos poucos.

A gerência da execução dos processos torna-se bastante complexa quando


diversos programas são carregados para a memória principal e processos
são criados para executá-los. Nesse cenário, novos processos podem ser
criados a qualquer momento, enquanto outros podem ser finalizados, e
também podem ocorrer interrupções advindas da rede ou do usuário. Para
ajudar nessa gerência, o ciclo de vida de um processo é bem definido em
estados e transições possíveis entre eles, como estudamos na unidade 8.

A troca de contexto, como é chamada a operação de interrupção de um


processo que está em execução e substituição dele por outro, é uma das
operações mais delicadas dentro do escopo da gerência de processos, por
isso demos a ela uma atenção maior na última unidade.

www.esab.edu.br 53
Continuando nossos estudos, nesta unidade vamos estudar com mais
detalhes a criação e a finalização de processos, usando como base
Tanenbaum (2010) e Deitel, Deitel e Steinbuhler (2005). Vamos iniciar
pela criação de processos.

9.1 Criação de processos


Existe um processo para cada programa que é executado no computador,
logo, todo SO precisa de um mecanismo de criação de novos processos.
De acordo com Tanenbaum (2010), há quatro eventos principais em um
SO que ocasionam a criação de novos processos:

• a inicialização do sistema;
• quando um processo existente executa uma função do SO capaz de
criar processos;
• quando o usuário requisita a criação de um novo processo;
• o início de uma tarefa em lote, em sistemas em lote.
O primeiro desses eventos é a inicialização do sistema. Como já
estudamos, todos os processos em um sistema são criados por outros
processos. A única exceção é justamente o primeiro processo a ser
executado quando ligamos o computador, que é inicializado pela Bios,
como vimos na unidade 4. Esse processo é o primeiro de diversos
processos do próprio SO. Esse e outros processos são criados pelo SO
ainda na inicialização do computador.

O último evento listado previamente − início de uma tarefa em lote, em


sistemas em lote − ocorre apenas em sistemas em lote, os quais estudamos
na unidade 2. Esses sistemas possuem grupos de tarefas, ou lotes. Cada
lote é tratado como um processo do computador, logo, toda vez que um
novo lote será executado, um processo é criado.

Porém, os outros dois eventos listados anteriormente (um processo


existente executa uma função do SO capaz de criar processos; o usuário
requisita a criação de um novo processo) são os mais comuns. De acordo
com Deitel, Deitel e Steinbuhler (2005), um processo pode ser iniciado
tanto por algum processo, executando uma função do SO que cria
processos, como também pelo próprio usuário, requisitando o início de
um processo.

www.esab.edu.br 54
No caso de uma ação por parte do usuário, como afirma Tanenbaum
(2010), a criação do processo pode ocorrer por comandos do usuário
tanto em interface textual quanto gráfica. No Windows, por exemplo,
o usuário pode entrar algum comando no Prompt de comando do
Windows ou dar um duplo clique no ícone de algum programa. Em
ambos os casos, aquele programa é executado e, para que isso ocorra, um
processo é criado para executar o programa.

A outra situação é quando um processo executa uma função do SO


que cria processos. Essa e diversas outras funções do SO são chamadas
de system calls, ou chamadas de sistema, e podem ser chamadas por
processos do usuário para realizar tarefas que apenas o SO possui
autorização para realizar, por exemplo, criar novos processos. Quando
um processo (processo-pai) cria um novo processo, esse novo processo é
chamado de processo-filho, como foi mostrado na Figura 8.

Como Tanenbaum (2010) salienta, a criação de processos é


implementada de forma diferente, dependendo do SO. Por exemplo, no
sistema Unix e seus descendentes e variações, a criação de um processo
é feita através da chamada de sistema fork. Essa chamada de sistema cria
um clone do processo que a está chamando. Entretanto, geralmente o
processo não quer criar outro processo idêntico, e sim executar outro
programa. Para isso, uma nova chamada de sistema se faz necessária para
mudar as informações do processo, permitindo que outro programa, com
outro espaço de endereçamento, seja executado.

Ainda de acordo com Tanenbaum (2010), nos sistemas Windows o


mecanismo é diferente. É possível criar um processo usando a chamada
de sistema CreateProcess, que recebe como parâmetros as configurações
necessárias para a execução do novo processo. A seguir, veremos outra
extremidade do ciclo de vida de um processo, isto é, a finalização do
processo.

www.esab.edu.br 55
9.2 Término de processos
Assim como ocorre com a criação de um novo processo, a finalização de
um processo também ocorre em momentos bem definidos. Tanenbaum
(2010) lista os seguintes momentos em que um processo é finalizado:

• finalização normal, por vontade do próprio processo;


• finalização por algum erro tratado pelo próprio processo;
• finalização por algum erro fatal que o processo causou;
• finalização por algum outro processo.
A forma mais comum de finalização de um processo é a primeira
da lista. Trata-se da finalização normal, quando o próprio processo
termina de realizar seus cálculos e finaliza a si mesmo. Isso pode ocorrer
implicitamente, quando o próprio código do programa chega ao fim
da sua execução ou explicitamente, quando o processo executa alguma
chamada de sistema como a ExitProcess presente nos sistemas Windows.

O segundo evento em que um processo é finalizado é quando algum


erro dentro do processo ocorre e o próprio processo decide terminar
sua execução. Isso ocorre, por exemplo, quando algum dado de entrada
fornecido para o processo está errado e, por esse motivo, o processo não
consegue realizar corretamente suas funções.

Existe outro tipo de erro causado pelo processo que também ocasiona o
seu término, mas dessa vez de uma forma involuntária. Esse erro ocorre
quando o processo tenta realizar uma operação inválida ou tenta executar
uma instrução do computador para a qual ele não tem autorização.
Outra razão muito comum para processos serem finalizados dessa forma
é quando o processo tenta acessar um endereço de memória que não
pertence a ele. Esses erros são fatais, e quando ocorrem, o próprio SO
finaliza o processo.

www.esab.edu.br 56
Por fim, processos também podem ser finalizados por outros processos.
De acordo com Tanenbaum (2010), no Unix existe a chamada de sistema
kill, e no Windows existe a chamada de sistema TerminateProcess. Para
encerrar outro processo, é preciso que o processo que está executando
a chamada de sistema possua autorização para tal. Um exemplo disso é
quando um processo-pai inicia um processo-filho para realizar uma tarefa
adjacente que ele necessita e, posteriormente, finaliza o processo-filho
quando ele não necessita mais das suas funcionalidades.

Assim, terminamos nossos estudos gerais sobre o gerenciamento


de processos. Ainda dentro desse assunto, estudaremos na próxima
unidade, o que são threads e como se relacionam com processos.
Posteriormente, estudaremos também o escalonamento de processos (que
já mencionamos nas últimas unidades). Até lá!

Estudo complementar
Nesta e nas últimas unidades você pôde
estudar o que são processos e como funciona o
gerenciamento de processos realizado pelo SO.
Como o entendimento a respeito de processos
é essencial para a sua formação, complemente
seus estudos lendo o material disponível neste
endereço.

www.esab.edu.br 57
10 Threads
Objetivo
Definir o conceito de thread, seu uso e suas vantagens em sistemas
computacionais.

Nas últimas unidades introduzimos o conceito de processo e estudamos


como o SO realiza o gerenciamento de todos os processos do
computador. Vimos que processos são programas em execução e que é
através da abstração de processos que o SO tem conhecimento de todos
os programas em execução no computador. Dessa forma, ele consegue
permitir que todos os programas utilizem os recursos do hardware com
facilidade, ao mesmo tempo em que gerencia de forma eficiente o uso
desses recursos.

Vimos também que processos podem ser criados e finalizados e que,


entre esses dois estados, um processo pode ser executado e interrompido
diversas vezes – seja por não ter instruções para executar, seja por decisão
do próprio SO de permitir que algum outro processo faça uso do
processador.

Nesta unidade, continuaremos estudando o gerenciamento de processos,


apresentando um dos conceitos mais importantes a respeito desse tópico,
o conceito de thread. Threads são componentes essenciais de processos
e por isso dedicaremos esta unidade ao seu estudo. Veremos o que são,
como funcionam e quais as vantagens de usarmos mais de uma thread
em sistemas computacionais. Para esse estudo, nos fundamentaremos
novamente em Tanenbaum (2010) e Silberschatz, Galvin e Gagne
(2001). Vamos começar vendo o que exatamente é uma thread.

www.esab.edu.br 58
10.1 O que é uma thread
Para entendermos o que é uma thread, vamos voltar ao exemplo do
cozinheiro (já utilizado na unidade 8) para mostrar como funciona o
gerenciamento de processos. O cozinheiro prepara vários pratos para o
jantar e cada prato deve ser feito conforme uma receita. Essas receitas são
como os programas na memória secundária, e o cozinheiro representa a
execução de um processo, em que cada receita é preparada seguindo suas
instruções.

Como vimos na unidade 8, o cozinheiro divide seu tempo preparando


dois ou mais pratos. Ele só consegue trabalhar em um prato de cada vez,
porém todos os pratos são feitos em conjunto.

Agora vamos supor que o cozinheiro precise preparar uma nova receita
grande e complexa. Para preparar essa receita em específico, o cozinheiro
pede ajuda para um outro cozinheiro, e ambos começam a preparar a
receita em conjunto, embora cada um realizando uma parte diferente da
receita. O cozinheiro poderia preparar a receita sozinho, porém dividir
o trabalho com outro cozinheiro permite que a receita fique pronta
mais rápido. Além disso, o preparo simultâneo de duas partes da receita
permite que recursos, como ingredientes, sejam compartilhados entre
elas. Por exemplo, se ambos os cozinheiros precisarem de batatas cozidas,
as batatas podem ser cozidas todas de uma vez só e então serem usadas
nas duas partes da receita ao mesmo tempo.

Com processos ocorre a mesma coisa. De forma geral, como afirmam


Silberschatz, Galvin e Gagne (2001) e Tanenbaum (2010), podemos
dizer que todo processo possui seu código, seus dados e um fluxo de
execução, o qual é controlado pelo seu contador do programa. O
código do processo é a receita, os dados são os ingredientes, e o fluxo
de execução é a ação de seguir as instruções da receita. Note que cada
cozinheiro representa um fluxo de execução da receita, embora esses
fluxos de execução se complementem. Apesar de os fluxos de execução
serem independentes, eles compartilham os mesmos ingredientes e
trabalham em conjunto para cumprir um objetivo.

www.esab.edu.br 59
Da mesma forma, um processo também pode ter mais de um fluxo de
execução, como se duas ou mais partes distintas do programa estivessem
sendo executadas ao mesmo tempo. Esse fluxo de execução do processo
é chamado de thread de execução. Ou seja, um processo possui código,
dados e uma thread de execução, e cada cozinheiro é visto como uma
thread. Todo processo sempre tem pelo menos uma thread, chamada
de thread principal do programa, que é o fluxo normal de execução do
processo, como descrito previamente. Essa thread é iniciada na primeira
instrução do processo e segue o fluxo de execução conforme foi nele
definido. A quantidade máxima de threads que um processo pode ter
varia dependendo do sistema, mas quase sempre é muito maior que a
quantidade de threads que o processo realmente precisa.

Assim como ocorre com os cozinheiros, threads são úteis porque


melhoram o desempenho dos processos, diminuindo o tempo que
eles levam para cumprir suas tarefas e também porque permitem que
diferentes partes do processo compartilhem os dados com os quais
estão trabalhando. A Figura 11 mostra um cenário em que duas threads
coexistem executando as instruções de um mesmo programa.

Thread 1 Código do programa


Contador do programa: Int funcao1(void){
linha1
linha 6 linha2
Pilha (variáveis locais etc.) linha3
linha4
Registradores linha5
Estado linha6
linha7
linha8
linha9
}
Int funcao2(void){
Thread 2 linha1
linha2
Contador do programa: linha3
linha 2 linha4
linha5
Pilha (variáveis locais etc.) linha6
Registradores }

Estado

Figura 11 – Visão de um processo com duas threads em que cada uma delas está executando uma
função do programa.
Fonte: Elaborada pelo autor (2013).

www.esab.edu.br 60
Veja que cada thread possui seu contador do programa, suas variáveis
locais, seu estado de execução etc. Note também que cada thread está
executando uma função do programa, embora nada impeça que elas
executem a mesma função. Na verdade, em termos de quais instruções
são executadas, as threads são bastante independentes.

Na prática, programadores criam programas com mais de uma thread


com o objetivo de realizar algumas tarefas de forma paralela (ou
pseudoparalela) e também para compartilhar dados entre elas.

10.2 Implementação de threads


Existem diferentes implementações de threads: elas podem ser
controladas em modo usuário ou modo kernel. Aqui, porém, iremos
focar nossos estudos em threads implementadas em modo kernel. Nesse
cenário, threads e processos são tratados como iguais pelo processador.
Como vimos na unidade 7, dizemos que a execução é pseudoparalela
porque na verdade, nesse cenário, existe apenas um processador, com um
único núcleo de processamento e por isso apenas uma thread do processo
pode executar a cada momento.

Em termos de como é realizada a execução do código, cada thread é vista


como um processo distinto. Por isso, sua execução é dividida da mesma
forma como o SO faz com os processos, e o usuário fica com a impressão
de que as threads estão executando paralelamente. Esse cenário, em
que os processos possuem várias threads, é chamado de multithreading.
Note que a maior diferença entre dois processos e duas threads de um
único processo é que as duas threads compartilham os mesmos dados,
enquanto um processo não tem acesso nenhum aos dados do outro
processo. Veremos a seguir em mais detalhes a implementação de threads.

Na Figura 7, vista na unidade 7, analisamos como era a visão de


um processo dentro da memória principal, com seu código, dados e
informações relevantes sobre o seu fluxo de execução. A Figura 12 mostra
uma versão ampliada da Figura 7, com mais detalhes e fazendo uso de
duas threads.

www.esab.edu.br 61
...
Código
#0 .............................
#1 .............................
#2 .............................
#3 .............................
#4 .............................
#5 .............................
#6 .............................
#7 .............................
#8 .............................
#n .............................

Dados
#0 .............................
#m .............................
Thread 1
Contador do programa (#2)
Pilha (variáveis locais etc.)
Registradores
Estado
Thread 2
Contador do programa (#8)
Pilha (variáveis locais etc.)
Registradores
Estado
Informações do processo
Processos-filhos
Arquivos abertos
Variáveis globais
etc.
...
Figura 12 – Visão de um processo com duas threads na memória principal.
Fonte: Elaborada pelo autor (2013).

www.esab.edu.br 62
Veja que as duas threads compartilham o mesmo código e os mesmos
dados, no entanto, possuem várias informações únicas de cada thread.
De acordo com Tanenbaum (2010), como cada thread é um fluxo de
execução do processo, cada uma precisa ter suas próprias informações a
respeito do seu fluxo de execução. Destas, a informação mais simples é o
contador do programa. Veja através das setas na Figura 12 que a Thread
1 está atualmente executando a instrução #2 do programa, enquanto a
Thread 2 está executando a instrução #8.

Além do contador do programa, cada thread possui sua pilha, que


é uma estrutura na memória que guarda dados de variáveis locais,
parâmetros, chamadas de funções etc. Estudaremos essa pilha com mais
detalhes quando formos estudar o gerenciamento de memória, a partir
da unidade 13.

Outras informações que cada thread possui são seus registradores. Como
já vimos antes, os registradores são dados muito importantes usados
durante a execução da thread e variam dependendo da arquitetura
do processador. Por fim, cada thread possui seu próprio estado de
funcionamento, assim como ocorre com os processos.

Porém, outras informações são independentes das threads e, portanto,


pertencem ao processo. Por exemplo, quais arquivos o processo abriu,
quais processos-filhos ele criou, quais são as variáveis globais usadas no
programa etc.

Em nosso cotidiano, há vários cenários em que é vantajoso manter


duas partes do programa em execução ao mesmo tempo. Para entender
melhor o uso de várias threads em um programa, vamos ver um exemplo
de programa de computador semelhante a um descrito por Tanenbaum
(2010). Suponha que estamos escrevendo um livro no computador
usando um editor de textos semelhante ao Microsoft Word. Em editores
de texto desse tipo, o texto aparece na página exatamente como será
impresso, com toda a sua formatação pronta.

Digamos que nosso livro já está com 500 páginas. Se por acaso formos
à página cinco e adicionarmos uma imagem no texto, todas as 495
páginas subsequentes precisam ser reformatadas. Formatar uma página

www.esab.edu.br 63
não é muito custoso, mas formatar 495 pode demorar alguns segundos,
dependendo do computador. Se o editor de textos tiver apenas uma
thread, assim que adicionarmos a imagem o editor começará a reformatar
todas as páginas seguintes e ficará travado para novas edições. Enquanto
ele estiver reformatando 495 páginas toda a interface do editor ficará
indisponível. Não conseguiremos mudar nada no texto, nem usar
qualquer ferramenta do Word. Enquanto a reformatação não acabar, não
poderemos adicionar nem um caractere novo ao texto. Dependendo do
SO, talvez não consigamos nem finalizar o processo normalmente.

A solução para esse problema é usar mais threads. Podemos ter uma
thread principal, a qual fica responsável por responder a qualquer ação do
usuário. Assim, se o usuário aperta uma tecla, essa thread é responsável
por adicionar a letra correspondente ao texto, na fonte, cor, tamanho
etc. definidos pelo usuário. Quando o texto é modificado, de forma que
uma reformatação de todas as páginas subsequentes precise ser realizada,
a thread principal se comunica com outra thread do processo, solicitando
que ela reformate o texto todo. Dessa forma, enquanto a outra thread
está reformatando o texto, a thread principal pode voltar a esperar por
comandos do usuário. Podemos, então, adicionar uma imagem na
página cinco e depois digitar abaixo dela uma legenda para a imagem e,
enquanto isso, sem percebermos, a outra thread está reformatando todas
as outras 495 páginas do texto por “baixo dos panos”.

Vimos nesta unidade os conceitos fundamentais do estudo de threads.


Aprendemos o que são threads, como elas funcionam e quais as
vantagens de usarmos mais de uma thread em um único processo. Agora
que sabemos os fundamentos a respeito de processos e threads, estamos
prontos para estudar o que é escalonamento e como ele funciona (tópicos
das nossas próximas duas unidades).

Tarefa dissertativa
Caro estudante, convidamos você a acessar o
Ambiente Virtual de Aprendizagem e realizar a
tarefa dissertativa.

www.esab.edu.br 64
11 Escalonamento – parte 1

Objetivo
Apresentar o conceito de escalonamento e sua finalidade.

Nas últimas unidades pudemos conhecer o conceito de processo e de


thread, e vimos quais informações são necessárias para o gerenciamento
de processos e threads pelo SO. Vimos também como o SO gerencia
o uso do processador, compartilhando-o entre todos os processos.
Considerando apenas computadores com um único núcleo de
processamento, vimos que apenas uma thread pode ser executada a cada
momento, e que o SO é o responsável por gerenciar o compartilhamento
do processador entre todas as threads existentes no computador.

Estudamos que há dois cenários principais em que uma thread pode


parar de executar e permitir que outra execute: (1) quando ela própria
interrompe sua execução para esperar algum dado de entrada vindo
tanto do usuário como da rede ou (2) quando ela é interrompida pelo
SO, provavelmente porque o SO decidiu que ela já executou por tempo
suficiente e é hora de deixar outra thread ser executada.

Quando um desses dois casos ocorre, de todas as outras threads prontas


para executar, qual delas o SO deve escolher? O SO deve selecionar
qualquer uma aleatoriamente? Deve escolher uma que não tenha sido
executada há bastante tempo? Além disso, quando o SO decide que
uma thread já foi executada por tempo suficiente? Esse tempo é fixo
para todas as threads? Certamente cada thread de cada processo possui
características de funcionamento bastante peculiares, e generalizar a
escolha de qual thread executar e por quanto tempo pode não ser uma
boa solução.

www.esab.edu.br 65
Nesta e na próxima unidade iremos responder a todas essas perguntas,
usando como base o trabalho de Tanenbaum (2010), Silberschatz, Galvin
e Gagne (2001) e Deitel, Deitel e Steinbuhler (2005). O conceito de
escalonamento está diretamente relacionado à resposta para todas essas
perguntas. Portanto, vamos logo definir o que é escalonamento e por que
o utilizamos.

11.1 O que é e por que usar escalonamento?


O tempo todo, durante a execução de programas de computador, ocorre
de a thread em execução ser interrompida, muitas vezes por vontade
própria. Nesse momento, o SO deve escolher, de todas que estão prontas
para executar, qual deverá passar a ser executada naquele momento.
De acordo com Tanenbaum (2010), Silberschatz, Galvin e Gagne
(2001) e Deitel, Deitel e Steinbuhler (2005), essa decisão é chamada
de escalonamento. Escalonar significa tirar uma thread do estado
Executando e passar a executar o código de outra thread. A decisão de
qual thread será escolhida faz parte do escalonamento.

A decisão de qual thread executar depende de diversos fatores, entre


eles, depende do próprio uso que o usuário faz do computador ou até
mesmo se existe um usuário para esse computador. Uma solução para o
problema do escalonamento seria, simplesmente, escolher qualquer outra
thread aleatoriamente e colocá-la em execução. Porém, como afirma
Tanenbaum (2010), um bom uso dos recursos do processador pode fazer
muita diferença no tempo de execução total das threads, aumentando a
importância de um bom escalonamento.

O componente do SO responsável por realizar o escalonamento, sempre


que ele se faz necessário, é chamado de escalonador. Todo SO possui
seu escalonador, e ele é um dos componentes mais importantes do SO,
sempre sendo executado em modo kernel (como visto na unidade 4),
independentemente do tipo de kernel. Há diversos fatores previsíveis que
escalonadores podem usar para tomar melhores decisões na hora de realizar
o escalonamento. Vamos discutir vários deles nesta e na próxima unidade.

www.esab.edu.br 66
Como o uso do computador pode variar bastante, os fatores relevantes
para o escalonador também podem variar. Por isso, diferentes
escalonadores devem existir. Veremos mais a respeito deles a seguir.

11.2 Tipos de escalonadores


Existem diferentes escalonadores para diferentes sistemas. Iremos descrever
aqui os principais fatores que levam à existência de diferentes escalonadores
e os estudaremos com mais detalhes na próxima unidade (momento em
que continuaremos nossos estudos a respeito desse assunto).

Como Silberschatz, Galvin e Gagne (2001) afirmam, é preciso fazer


um uso eficiente do processador, o que afeta bastante o funcionamento
do escalonador. O próprio ato de escalonar é custoso, principalmente
por causa das trocas de contexto, e, além disso, não podemos realizar
escalonamentos frequentes, pois isso pode prejudicar o desempenho. Toda
vez que um escalonamento é realizado, o SO deve salvar o contexto todo
da thread e do processo que estava executando, deve realizar uma troca
de contexto para que o escalonador seja executado e, então, o escalonador
precisa decidir qual thread de qual processo será executada em seguida.

Depois, o processo escolhido deve ser iniciado e uma nova troca de


contexto deve existir para permitir a execução do novo processo. De
acordo com Tanenbaum (2010), essas trocas de contexto também são
custosas porque não se está apenas trocando um processo por outro, mas
também modificando o modo de execução do processador, passando
do modo usuário para o modo kernel e depois novamente para o modo
usuário. Note que, no escalonamento, pode ocorrer de nenhuma thread
estar pronta para executar. Ao invés de não colocar nenhum processo
em execução, os escalonadores costumam colocar em execução processos
vazios definidos pelo SO.

www.esab.edu.br 67
Tanenbaum (2010) lista três tipos principais de sistemas computacionais
e o que se espera de um bom escalonamento em cada um deles. Os tipos
de sistemas são:

• sistemas em lote: em geral, sistemas em lote não possuem usuários,


logo, não há necessidade de respostas rápidas, mas o tempo total
de execução das tarefas deve ser o menor possível. Como a troca
de contexto realizada a cada escalonamento possui um custo de
processamento, realizar muitos escalonamentos pode prejudicar o
desempenho do sistema. Portanto, deve-se evitar a realização de
escalonamentos em grande quantidade;
• sistemas interativos: são aqueles em que o usuário interage com
o sistema, como os computadores pessoais, os quais usamos
no nosso dia a dia. Esses sistemas, por outro lado, precisam ter
escalonadores que a todo o momento se preocupam em fazer com
que o usuário não perceba lentidão no sistema, ou seja, threads que
mexem diretamente com a interface visual dos programas devem ser
priorizadas, por exemplo;
• sistemas de tempo real: em sistemas de tempo real, as tarefas
precisam ter tempo de execução previsível, e o escalonador deve se
preocupar em não prejudicar essa previsibilidade.
Além dos tipos de sistema, o comportamento dos processos também
pode afetar muito a forma como o escalonador funciona. Podemos
dividir os processos em um computador em processos limitados pelo
processador (ou CPU-bound) e processos limitados pela E/S (ou I/O-
bound). Um processo limitado pelo processador é um processo que passa
a maior parte do seu tempo de execução realizando cálculos.

Esses processos limitados pelo processador, quando começam a realizar


cálculos, ficam bastante tempo executando antes de serem interrompidos.
Tanenbaum (2010) afirma que esses processos possuem surtos longos de
uso do processador e esporádicas esperas por E/S. Por outro lado, um
processo limitado pela E/S é um processo que passa a maior parte do seu
tempo esperando dados de E/S, ou seja, possui surtos curtos de uso do
processador e períodos longos de espera por E/S.

www.esab.edu.br 68
A Figura 13 ilustra dois tipos de processos ao longo do tempo, um
limitado pelo processador (a) e outro limitado pela E/S (b).

Processador sendo usado por muito tempo Processador sendo pouco usado

a)

b)

Momentos em que o processo está esperando por E/S


Tempo
Figura 13 – Linha do tempo mostrando um processo limitado pelo processador e outro limitado pela E/S.
Fonte: Adaptada de Tanenbaum (2010).

De forma geral, podemos dizer então que o tipo de funcionamento


do escalonador é bastante influenciado por fatores como o custo para
realizar cada escalonamento, o tipo de cada processo em execução
(limitado pelo processador ou pela E/S) e os tipos de programas que
costumam executar no programador, em termos de funcionalidades.
Por exemplo, sistemas em lote possuem necessidades diferentes de
computadores pessoais, que, por sua vez, possuem necessidades diferentes
de sistemas de tempo real, em que o tempo para realizar a maioria das
tarefas deve ser sempre previsível.

Por fim, outro fator que diferencia os escalonadores é se eles são capazes
ou não de interromper uma thread em execução quando quiserem. Se
o escalonador é capaz de interromper a thread quando quiser, dizemos
que ele é preemptivo. Se o escalonador não pode interromper a thread,
ou seja, ele sempre espera a thread finalizar-se sozinha ou ser bloqueada
por causa de alguma espera por E/S, então dizemos que o escalonador
é não preemptivo. Estudaremos esses dois tipos de escalonadores na
próxima unidade.

Dessa forma, terminamos esta unidade introdutória a respeito de


escalonadores. Na próxima unidade aprofundaremos nossos estudos a
respeito desse essencial componente de todo SO.

www.esab.edu.br 69
12 Escalonamento – parte 2
Objetivo
Aprofundar o estudo a respeito de escalonamento, apresentando o
conceito de escalonamento preemptivo e não preemptivo, definindo
o que são critérios e políticas de escalonamento.

Na unidade anterior começamos a estudar o que é escalonamento e


como ele é realizado. Vimos que escalonamento é como chamamos a
escolha que o SO tem que fazer a respeito de qual thread deve executar
quando a thread que estava em execução é interrompida. O componente
do SO responsável por isso se chama escalonador. Nesta unidade, com o
apoio teórico de Deitel, Deitel e Steinbuhler (2005), Silberschatz, Galvin
e Gagne (2001) e Tanenbaum (2010), vamos continuar nossos estudos
sobre escalonamento. Para começar, veremos o que são escalonadores
preemptivos e não preemptivos.

12.1 Escalonamento preemptivo e não preemptivo


De acordo com Deitel, Deitel e Steinbuhler (2005), Silberschatz, Galvin
e Gagne (2001) e Tanenbaum (2010), escalonamento não preemptivo
é aquele em que o escalonador nunca interrompe por vontade própria
a execução de alguma thread. Em outras palavras, quando ele decide
colocar uma thread em execução, ela continuará executando enquanto
quiser, pois o escalonador jamais irá interrompê-la. Por outro lado,
escalonamento preemptivo é aquele no qual o escalonador interrompe,
de tempos em tempos, a thread em execução e a substitui por outra,
permitindo que outra thread execute.

Note que o escalonamento que estudamos nas últimas unidades é o de


tipo preemptivo, que é o mais comum nos SOs modernos. Sistemas em
lote e sistemas de tempo real geralmente não necessitam de escalonadores
preemptivos, mas em sistemas interativos, como os que usamos no nosso
dia a dia, o escalonamento preemptivo é essencial.

www.esab.edu.br 70
Para entendermos mais a fundo esses dois tipos de escalonamento,
vamos ver quais são todas as situações nas quais um escalonamento se
faz necessário. Como Tanenbaum (2010) afirma, a questão de quando
escalonar é uma das mais fundamentais no funcionamento de um
escalonador.

Em primeiro lugar, um escalonamento deve ser realizado quando um novo


processo é criado. Após a criação, tanto o processo-pai quanto o processo-
filho estão no estado Pronto e poderiam ser executados. Nesse momento, o
escalonador deve decidir qual dos dois executar. Da mesma forma, quando
um processo é finalizado, o escalonador também deve decidir que outro
processo executar, pois o anterior não está mais disponível.

Um caso muito comum em que o escalonamento é necessário é quando


uma thread bloqueia a si mesma (vai para o estado Esperando), seja
esperando por algum comando vindo do usuário, seja por algum dado
vindo de um dispositivo de E/S. Como Tanenbaum (2010) afirma, o
motivo para a thread ter bloqueado a si mesma pode afetar a escolha de
qual será o próximo processo a ser colocado em execução. Por exemplo,
se a thread se interrompeu para esperar outra thread terminar de ser
executada, o escalonador pode preferir que essa outra thread execute em
seguida, para permitir que a primeira volte a executar logo.

Por fim, existem momentos em que o hardware do computador


interrompe a execução da thread que está executando, o que é chamado
de interrupção de hardware. Por exemplo, quando o computador está
ligado e o usuário conecta ao computador um dispositivo de memória
Flash com conexão USB (também chamado informalmente de pen
drive), o SO precisa identificar o dispositivo e permitir que o usuário
explore os arquivos que existem nele. Quando o usuário conecta esse
dispositivo ao computador, o hardware percebe que um dispositivo foi
conectado e avisa o SO, que imediatamente interrompe a thread que
estiver executando e coloca em execução sua rotina de gerenciamento de
E/S (que estudaremos a partir da unidade 21). Logo após essa rotina ser
executada, o escalonador precisa decidir qual processo será executado em
seguida. Se algum processo estiver justamente esperando pela conexão de
algum dispositivo USB, o escalonador pode permitir que esse processo
execute imediatamente.

www.esab.edu.br 71
Processos prontos

Finalizados
Esperando

Executando
Recém-criados

Escalonador

Figura 14 – Escalonador controlando qual thread está executando.


Fonte: Elaborada pelo autor (2013).

A Figura 14 mostra o escalonador desempenhando seu papel, tendo


conhecimento de todos os processos do computador e controlando
qual thread deve ser executada. Todos esses casos de escalonamento
descritos ocorrem tanto em escalonadores preemptivos quanto em não
preemptivos. Nos escalonadores não preemptivos, acabam aqui os casos
nos quais o escalonador é executado. O usuário começa a executar
um processo e esse processo ficará em execução até que finalize ou
interrompa sua execução esperando algum dado de entrada. Aí então
outro processo pode entrar em execução. Se algum processo começar a
executar e nunca se interromper à espera de dados de entrada, então esse
processo permanecerá em execução até que se finalize. Por outro lado,
os escalonadores preemptivos, que são nosso principal objeto de estudo
aqui, atuam de forma mais ativa no controle do que está em execução.

Como mostramos na Figura 9 (na unidade 7), uma forma de ativamente


controlar a execução dos processos é permitir que todos executem
um pouco de cada vez bloqueando de vez em quando o processo em
execução e deixando que outro execute em seu lugar. Mas quanto tempo

www.esab.edu.br 72
deixar cada thread executando? Além disso, ainda não respondemos
uma das principais questões a respeito de escalonamento: qual thread
executar depois que o tempo permitido para a thread atual se esgota?
Para respondermos a essas duas perguntas, precisamos primeiro entender
que critérios de escalonamento existem, como veremos a seguir.

12.2 Critérios de escalonamento


Toda vez que escalonamos, estamos buscando um melhor desempenho
em algum aspecto do nosso sistema. Se duas atividades podem ser
realizadas de forma pseudoparalela, é interessante que o SO suporte e
implemente isso. Quando interrompemos sua execução e permitimos
que outra thread execute, estamos fazendo isso com um propósito,
porém, como vimos na unidade anterior, esse propósito varia conforme o
tipo sistema.

Como afirma Tanenbaum (2010), todo sistema, de forma geral,


tem três critérios principais de escalonamento: ele busca por (1) um
escalonamento que priorize o equilíbrio do sistema, (2) o cumprimento
das políticas definidas e (3) o compartilhamento justo dos recursos
entre os processos. Buscar o equilíbrio do sistema significa manter
todos os componentes de hardware ocupados a maior parte do
tempo. Um mau sinal é o processador ficar ocioso por muito tempo
enquanto algum dispositivo de E/S está trabalhando em seu máximo.
O compartilhamento justo dos recursos entre os processos consiste em
simplesmente permitir que todo processo execute tanto tempo quanto
for justo para ele. Isso significa que dois processos com as mesmas
características de funcionamento e executados no mesmo sistema,
deveriam ser executados por períodos de tempo iguais. Por fim, como
veremos ainda nesta unidade, cada escalonador segue uma política de
escalonamento, que dita como o escalonador deve funcionar, e espera-se
que ele sempre siga essa política, qualquer que ela seja.

Tanenbaum (2010) também lista critérios de escalonamento específicos


para cada sistema. Em sistemas em lote, existem grupos de tarefas
a serem realizadas, e o escalonamento deve funcionar de forma que
seja maximizado o número de tarefas por hora, minimizado o tempo

www.esab.edu.br 73
de execução de cada tarefa e mantendo o processador ocupado pelo
maior tempo possível. Em sistemas de tempo real, o principal critério é
simplesmente cumprir todos os prazos do sistema.

Todavia, em sistemas interativos, o cenário é diferente. O usuário está o


tempo todo olhando para a tela do computador e a resposta visual que
ele recebe dos programas é muito importante. A thread responsável pela
interface gráfica do programa que está ocupando a tela do computador é
sempre tratada como uma das threads de maior importância. Quando o
usuário muda de janela, outra thread passa a ser mais importante. Logo,
podemos dizer que um critério para esse tipo de sistema é minimizar o
tempo de resposta para qualquer ação que o usuário tomar. Tarefas que o
usuário já espera que sejam lentas podem ser lentas, enquanto outras que
o usuário espera que sejam sempre rápidas, devem ser executadas com
mais urgência.

Esses três tipos de sistemas têm critérios de escalonamento bem distintos,


ou seja, possuem prioridades diferentes em termos do que o escalonador
deve buscar atingir. Para alcançar os objetivos, foram definidas políticas
de escalonamento, as quais estudaremos a seguir.

12.3 Políticas de escalonamento


Existem diversas políticas de escalonamento, também chamadas de
algoritmos de escalonamento, e o objetivo de cada uma é definir como
o escalonador funcionará. Vamos focar nossos estudos nas políticas de
escalonamento usadas nos sistemas interativos, que são os que estamos
mais habituados a usar.

A política de escalonamento mais conhecida e simples para sistemas


interativos, que inclusive foi usada como exemplo na Figura 9 da
unidade 7, se chama round-robin, ou rodízio. De acordo com
Silberschatz, Galvin e Gagne (2001), nessa política o SO define um
intervalo de tempo, chamado quantum, e cada thread de cada processo
do computador tem a permissão de executar ininterruptamente por até
um quantum de tempo. Para Tanenbaum (2010), um quantum entre 20
e 50 milissegundos é aceitável, enquanto Silberschatz, Galvin e Gagne
(2001) falam de um quantum que varia entre 10 e 100 milissegundos.

www.esab.edu.br 74
O escalonador possui uma fila de todas as threads e sempre coloca em
execução o primeiro elemento da fila. A thread então começa a executar
e seu tempo de execução é calculado. Se passar um quantum de tempo e
a thread ainda estiver executando, o escalonador interrompe a thread, a
coloca no final da fila e põe em execução o primeiro elemento da fila. O
mesmo ocorre se a thread for bloqueada esperando dados de E/S antes
do fim do seu quantum, ou seja, ela também vai para o final da fila e o
próximo elemento é executado.

Processo atual Próximo processo

B F D G A

(a)
Processo atual

F D G A B

(b)

Figura 15 – Exemplo de execução da política de escalonamento round-robin.


Fonte: Tanenbaum (2010, p. 95).

A Figura 15 mostra a política rounb-robin na prática. Em um primeiro


momento (a), o processo B executa e o F é o próximo na fila para
executar. Em um segundo momento, o processo F começa a ser
executado e o processo B vai para o final da fila.

Existe outra política que implementa uma fila de múltiplos níveis, em


que cada nível possui processo com uma prioridade específica. Uma
característica comum em SOs é que cada thread possui uma prioridade
de execução. Uma thread responsável pela interface gráfica geralmente
tem alta prioridade de execução. Por outro lado, a thread do SO que
verifica se existem atualizações para o SO Windows, pode executar
em uma prioridade bem mais baixa. Segundo essa política, após uma
thread ser interrompida, a próxima a executar será a thread com maior
prioridade disponível, ao invés de simplesmente a próxima da fila. Nessa
política deve haver, porém, uma forma de evitar que threads de baixa
prioridade não sejam executadas jamais.

www.esab.edu.br 75
Existem diversas variações das duas políticas definidas anteriormente. Há
políticas que usam múltiplas filas, uma para cada prioridade, mesclando
características dessas duas políticas. Há outras políticas, contudo, que
fazem estimativas de quanto tempo elas acham que cada thread executará
e, então, dão prioridade às threads que tendem a executar por menos
tempo, abordagem que funciona bem em sistemas em lote.

Terminamos assim essa segunda unidade sobre escalonamento, que


também finaliza nossos estudos a respeito do gerenciamento de
processos. Nesta unidade estudamos a classificação de escalonadores
em preemptivos e não preemptivos e vimos como funciona cada um
dos dois. Vimos que o escalonamento preemptivo existe para que o
SO realize um melhor controle a respeito de como os processos são
executados. Como estudamos, para que esse controle seja mais bem
realizado, existem diversos critérios de escalonamento os quais os
escalonadores precisam cumprir, e diversas políticas de escalonamento
que definem como pode funcionar o escalonador.

Na próxima unidade vamos começar a estudar o gerenciamento de


memória!

Estudo complementar
Agora que você já estudou o que é escalonamento
e quais são os diferentes tipos de escalonamento,
seus critérios e suas políticas, leia o material
disponível aqui, como uma forma de
complementar seus estudos e também conhecer
um pouco mais sobre outras políticas de
escalonamento.

www.esab.edu.br 76
Resumo

Nas últimas seis unidades estudamos sobre o gerenciamento de processos.


Vimos que processo é um programa em execução. Um processo tem
suas instruções e dados guardados na memória principal, e cada processo
possui um ou mais fluxos de execução que executam essas instruções e
manipulam esses mesmos dados. Cada fluxo de execução de um processo
é chamado de thread.

Vimos também que, para gerenciar todos os processos e threads do


computador, o SO guarda tabelas com diversas informações a respeito
dos processos e threads, e sempre coloca em registradores as informações
mais importantes a respeito do processo ou thread que está em execução
em cada momento.

Vimos que as threads de um processo compartilham os mesmos dados


na memória, porém cada thread possui seus próprios registradores e
sua própria pilha, onde são guardados os dados que estão sendo usados
durante a execução da thread. Um dos registradores que cada thread
possui é o seu contador do programa, que sempre informa qual é a
próxima instrução do programa que a thread deve executar.

Vimos que a troca de uma thread em execução por outra é chamada de


escalonamento, e que o escalonador do SO possui a responsabilidade de
controlar qual thread ou processo está em execução e também de decidir
qual é a próxima thread ou processo a executar.

www.esab.edu.br 77
Os escalonadores podem ser preemptivos ou não preemptivos. Nos
escalonadores não preemptivos, o escalonador escolhe uma thread para
executar e essa thread fica executando até que ela mesma se interrompa
ou finalize sua execução, pois o escalonador não tem o poder de
interromper sua execução. Por outro lado, um escalonador preemptivo
pode interromper a execução de uma thread quando quiser, para permitir
que outra thread seja executada naquele momento.

Nas próximas unidades, vamos começar a estudar um novo aspecto do


SO, o gerenciamento de memória.

www.esab.edu.br 78
13 Abstração da memória

Objetivo
Contextualizar o que é a memória e seu espaço de endereçamento.

Estudamos em detalhes o que são processos e threads e qual a relação


destes com o principal componente de hardware do computador: o
processador. Vimos que o processador é responsável por executar as
instruções de todos os programas que o usuário deseja executar. Vimos
também que o SO é responsável por controlar e gerenciar a execução
de todos esses programas por meio da criação de estruturas chamadas
processos e threads.

Outro componente essencial de todo computador, e que já foi


comentado inúmeras vezes nesta e em outras disciplinas é a memória.
Já estudamos superficialmente o que é a memória, mas nesta e nas
próximas unidades vamos nos aprofundar nos estudos a respeito do seu
funcionamento. Vamos também conhecer em detalhes como o SO realiza
o gerenciamento desse importante recurso do computador.

Nesta unidade, fundamentaremos nossos estudos no trabalho de


Tanenbaum (2010). Para iniciar, vamos contextualizar o que é a memória.

13.1 O que é a memória?


Como vimos na unidade 4, a memória desempenha um papel muito
importante no computador. Um computador, normalmente, possui
uma ou mais memórias voláteis e uma ou mais memórias não voláteis.
Memória não volátil é aquela que mantém os dados armazenados mesmo
quando o computador é desligado. O exemplo mais comum de memória
não volátil é o disco rígido. Esse tipo de memória também é chamado
memória secundária e será o foco de estudo nas unidades 19 e 20.

www.esab.edu.br 79
Nesta e nas próximas unidades vamos focar nossos estudos nas memórias
voláteis. A memória volátil é aquela que armazena os dados apenas
enquanto o computador está ligado.

Figura 16 – Memória RAM.


Fonte: <www.freedigitalphotos.net>.

Como já estudamos, a maior vantagem das memórias voláteis é que elas


são bem mais rápidas que as memórias não voláteis. O principal exemplo
de memória volátil em um computador é a memória RAM, também
chamada de memória principal. Além da memória principal, de acordo
com Tanenbaum (2010), a maioria dos computadores modernos carrega
também outras memórias menores e de alta velocidade, chamadas de
caches, que também são memórias voláteis.

Por serem mais rápidas, é com esse tipo de memória que o processador
se comunica diretamente. As instruções dos programas em execução
são buscadas na memória principal para serem executadas, e os dados
desses programas ficam guardados nessa memória durante a execução. O
próprio SO também ocupa a memória principal.

No entanto, a memória principal do computador é um recurso limitado


e nunca é suficiente para todas as atividades que o usuário realiza.
Segundo Tanenbaum (2010), isso ocorre porque, com o passar do
tempo, os computadores passam a exigir mais memória, pois esta é mais
utilizada pelos programas, que tendem a ser utilizados simultaneamente
pelo usuário.

Quando diversos programas utilizam os recursos de memória ao


mesmo tempo, é necessário que o computador tenha alguma forma
de gerenciamento de memória, mesmo que a memória disponível seja
suficiente.

www.esab.edu.br 80
O SO é o responsável por realizar esse gerenciamento de memória
de forma muito semelhante ao gerenciamento de processos, o qual já
estudamos nas unidades 8 e 9. No caso dos processos, o processador é
o recurso compartilhado. Esse recurso é compartilhado em função do
tempo, ou seja, durante cada instante de tempo, o processador executa
um processo, e em um instante seguinte pode passar a executar outro
processo e assim por diante, compartilhando o recurso.

No caso da memória, o recurso é espacial, e não temporal. Por exemplo,


um programa ocupa um pedaço da memória, enquanto outro programa
ocupa outro pedaço da memória. Assim como o SO cria a abstração de
um processo para representar um programa em execução, como você
verá a seguir, criamos a abstração de um espaço de endereçamento para
representar um programa ocupando a memória.

13.2 Espaços de endereçamento


Dizemos que a memória principal é composta por uma lista de endereços
de memória, onde, em cada endereço, podemos armazenar um dado.
Como a memória principal é usada por todos os programas que estão em
execução, deve haver uma forma de permitir que cada programa utilize a
memória sem atrapalhar os outros.

Isso é possível com a utilização de espaços de endereçamento. Um espaço


de endereçamento é um pedaço da memória principal que um processo
pode utilizar para armazenar seus dados. No espaço de endereçamento
de um processo, é possível guardar apenas dados daquele processo. Esse
espaço é definido quando o processo é criado e deixa de existir quando o
processo é finalizado.
Programa na memória principal Programa armazenado na
memória secundária
0 #include <stdio.h>
1 int main (void) { #include <stdio.h>
2 int $6 = 9;
3 printf ($5); int main (void) {
4 } int a = 9;
5 “Teste” printf (“Teste”);
6 9 }
Figura 17 – Visão básica de um programa ocupando a memória secundária e depois a memória principal.
Fonte: Elaborada pelo autor (2013).

www.esab.edu.br 81
Como já estudamos, quando um programa é executado, seu código,
dados e informações sobre o processo são colocados na memória
principal. A Figura 17 mostra um simples programa escrito em C
ocupando a memória secundária e esse mesmo programa ocupando seu
espaço de endereçamento na memória principal durante sua execução.
Embora o exemplo seja bastante simples, o objetivo dessa figura é
mostrar como o programa aparece quando está ocupando um espaço
de endereçamento da memória principal. Para facilitar o entendimento,
toda a abstração da memória foi simplificada.

Veja que, primeiramente, armazenamos o código do programa, do


endereço 0 ao endereço 4. Em uma memória real, não armazenaríamos
esse código em linguagem C, e sim em linguagem de máquina, mas
mantivemos dessa forma para facilitar a compreensão. Cada variável ou
constante do programa é armazenada separadamente do código, como
podemos ver nos endereços 5 e 6. Dessa forma, quando a instrução no
endereço 2 é executada, uma variável numérica é criada no endereço 6
e nela é armazenado o número 9. Note que estamos usando o caractere
‘$’ para indicar endereços de memória. A escolha do endereço 6 para
armazenar o número 9 é feita durante a compilação do programa, ou
seja, já está escrito no código em linguagem de máquina que no endereço
6 deve ser colocado o número 9. É dessa forma que os dados dos
programas ficam armazenados internamente. Por fim, na instrução do
endereço 3, a string no endereço 5 é apresentada ao usuário.

O código do endereço de 0 a 4 e os dados nos endereços 5 e 6 formam o


que chamamos de espaço de endereçamento do programa. Ele consiste em
um trecho da memória que pode ser utilizado pelo programa e só por esse
programa. Outros programas devem usar outros espaços de endereçamento.

Como vimos nas unidades anteriores, além do código e dos dados, cada
programa também guarda na memória informações sobre o processo
e suas threads, como program counter etc. Essas informações foram
omitidas na Figura 17 apenas para simplificar o exemplo.

www.esab.edu.br 82
Essa é uma visão bem simples da utilização da memória principal por
parte de um programa, porém o exemplo nos permite visualizar como
um programa fica armazenado na memória e como se parece o seu
espaço de endereçamento. Em um cenário real, não existe apenas um
processo em execução e nem sempre há espaço suficiente na memória
para armazenar todos os processos ao mesmo tempo.

O que acontece, então, quando queremos executar um novo programa


sem finalizar o anterior? Em quais endereços da memória colocaríamos
seu código e seus dados? Como acabamos de comentar, os endereços
usados pelo programa, como o endereço 6 para guardar o número 9,
são fixos e estabelecidos na compilação. E se quisermos executar um
programa que deseja usar o endereço 6 da memória para outro fim? E se
o código desse outro programa também devesse ser armazenado a partir
do endereço 0? O programa que estávamos executando seria sobrescrito?

Sem um correto gerenciamento da memória, de fato, o programa que


estávamos executando seria sobrescrito, o número 9 no endereço 6
seria apagado para ser usado pelo novo programa e não conseguiríamos
executar dois programas ao mesmo tempo.

Assim, terminamos esta unidade. Já entendemos como um programa


é armazenado na memória principal e vimos o que é o seu espaço de
endereçamento. A partir da próxima unidade vamos entender como o
SO faz para permitir que vários programas usem a memória principal ao
mesmo tempo e como ele faz para gerenciar o uso da memória quando
há mais programas em execução do que espaço na memória.

Saiba mais
Nesta unidade você iniciou seus estudos a respeito
da memória principal do computador e de como
ela funciona. Para conhecer um pouco mais a
respeito desse componente de hardware e se
preparar melhor para as próximas unidades,
assista ao vídeo disponível clicando aqui.

www.esab.edu.br 83
Gerenciamento de memória –
14 parte 1
Objetivo
Apresentar técnicas básicas de gerenciamento de memória.

Na unidade anterior começamos a estudar sobre o gerenciamento


de memória realizado pelo SO, no entanto, inicialmente, apenas
introduzimos os conceitos básicos necessários aos nossos estudos.
Estudamos que o espaço de endereçamento é o trecho da memória
disponível para ser usado pelo programa tanto para armazenar o
código do programa como também para organizar seus dados e outras
informações que ajudam a gerenciar a execução do processo.

Porém, o espaço de endereçamento simples que estudamos na unidade


anterior não permite a execução de mais de um programa ao mesmo
tempo no computador e também não confere se a memória é grande
o suficiente para armazenar o programa inteiro. Esse gerenciamento é
realizado pelo SO e será estudado em detalhes nesta unidade.

Novamente, fundamentaremos nossos estudos no trabalho de


Tanenbaum (2010). Vamos iniciar os estudos desta unidade
introduzindo a gerência de memória realizada pelo SO.

14.1 Introdução ao gerenciamento de memória


Todos os endereços na memória principal são chamados de endereços
físicos, pois eles existem fisicamente, dentro do barramento do hardware
da memória principal. Isso significa que, se um programa coloca um
dado no endereço 6, o dado é de fato colocado no endereço 6 da
memória principal. Porém, e se o endereço 6 já estiver sendo usado
por outro programa? Nesse caso, o dado será colocado no endereço 6
e o outro programa perderia o seu dado armazenado na memória. Esse

www.esab.edu.br 84
cenário jamais pode ocorrer, pois o SO não pode permitir que programas
percam seus dados na memória. Na prática, usamos nos programas o
conceito de endereço virtual em vez de trabalharmos diretamente com
endereços físicos. Vamos entender agora como isso funciona: após
criarmos um programa e o compilarmos, o compilador determina que
certo dado precisa ser guardado no endereço 6, por exemplo, sendo que o
espaço de endereçamento do programa sempre inicia no endereço 0.

No momento em que o programa for executado, o SO não coloca o


programa na memória a partir do endereço 0. Por conveniência, digamos
que o SO coloque o programa na memória principal a partir do endereço
1.000. Dessa forma, quando o programa solicitar o armazenamento do
dado no endereço 6, o SO vai converter o valor 6 em 1.006 e guardá-lo
no dado do endereço 1.006.

O programa continua achando que está no endereço 0 e guardando


o dado no endereço 6, que são endereços virtuais, pertencendo ao
que chamamos de espaço de endereçamento virtual do programa.
Porém, na prática, o SO pode colocar o programa e seus dados em
outro lugar da memória principal, onde for mais conveniente para ele,
fazendo com que o programa possua endereços físicos diferentes. Note
que um determinado programa sempre irá possuir o mesmo espaço
de endereçamento virtual, com os endereços virtuais definidos na sua
compilação. Porém, quando o programa é executado, pode possuir
diferentes endereços físicos. Para que funcione corretamente, toda vez
que o programa acessar algum endereço, o SO deve converter o endereço
virtual do programa em um endereço físico da memória.

De acordo com Tanenbaum (2010), o SO guarda, para cada programa


na memória principal, um registrador-base, que indica em qual endereço
físico da memória o programa inicia, e um registrador-limite, que indica
em qual endereço o programa termina. Como veremos a seguir, é por
meio desses dois registradores que o SO sabe converter endereços virtuais
em endereços físicos. Veja com atenção a Figura 18, que mostra três
programas com seus endereços virtuais e físicos, respectivamente, antes e
depois de serem colocados na memória principal.

www.esab.edu.br 85
Memória principal Programa A
0 $3 = 20; 0 $3 = 0;
1 $3 = $3 * 3; 1 $4 = $3 + 1;
2 printf (”%d”, $3); 2 printf (”%d”, $4);
3 60 3 0
4 $7 = 0; 4 1
5 $8 = $7 +1; Programa B
6 printf (”%d”, $8); 0 $3 = 20;
7 0 1 $3 = $3 * 3;
8 1 2 printf (”%d”, $3);
9 $11 = 10; 3 60
10 printf (”%d”, $11);
11 10 Programa C
0 $2 = 10;
1 printf (”%d”, $2);
2 10
Figura 18 – Três programas com seus endereços virtuais e físicos
antes e depois de serem colocados na memória principal.
Fonte: Elaborada pelo autor (2013).

Na Figura 18 temos um exemplo no qual iniciamos a execução de três


programas e os colocamos na memória principal. Os três programas
aparecem à direita com seus endereços virtuais sempre iniciando em 0, cada
um indicado com uma cor diferente. O código dos programas está escrito
em uma linguagem semelhante à C, porém de forma bastante simplificada,
mostrando o endereço das variáveis em vez de mostrar seus nomes.

O primeiro programa a ser executado é o programa B, que possui três


linhas de código e uma linha de dados. Como inicialmente não há
nenhum programa na memória, podemos colocar o programa B no topo
e manter uma relação direta entre seus endereços virtuais e os endereços
físicos da memória.

O trabalho de gerência do SO inicia, de fato, quando decidimos executar


o programa A. O programa A ocupa os endereços de 0 a 4, porém já
temos o programa B do endereço 0 a 3. Para possibilitar a execução do
programa A, devemos colocá-lo em outro local da memória. Como o
endereço 4 em diante está desocupado, colocamos o programa A no
endereço 4 a 8. Para lembrarmos onde guardamos o programa A, criamos

www.esab.edu.br 86
um registrador-base que indica em qual endereço o programa A começa
(endereço 4) e um registrador-limite, que indica em qual endereço o
programa A termina (endereço 8).

Veja que nesse momento podemos notar claramente a diferença entre


endereços físicos e endereços virtuais. O programa A continua achando
que ocupa do endereço 0 ao endereço 4, pois esses endereços são fixos.
No entanto, esses endereços são virtuais, pois a localização do programa
A durante a execução pode ser outra. Dessa forma, embora o programa A
possua os endereços virtuais de 0 a 4, ele ocupa os endereços físicos de 4 a 8.

Vamos ver agora como é realizada a execução do programa A na prática,


usando como base a primeira instrução do programa. Como podemos
ver, a primeira instrução desse programa, localizada no endereço virtual
0, coloca o valor 0 no endereço virtual 3, o que pode ser visto a seguir:
0 $3 = 0;

Porém, durante a execução, somamos o registrador-base do programa (4)


aos endereços presentes no código, da seguinte forma:
0+4 $3 + 4 = 0;

Veja que somamos 0 + 4, e o código que estava no endereço virtual 0


passa a estar no endereço físico 4. Da mesma forma, somamos $3 +
4, ou seja, o endereço virtual $3 se transforma no endereço físico $7.
Finalmente, o código que é realmente executado é apresentado a seguir:
4 $7 = 0;

Veja que é exatamente o código que aparece na coluna à esquerda da


Figura 18. Assim, para cada instrução do programa que referencie algum
endereço, somamos o registrador-base a esse endereço e, então, sempre
conseguimos acessar o endereço físico correto no qual se encontram os
dados e código do programa.

www.esab.edu.br 87
Tente agora descobrir o registrador-base e o registrador-limite do
programa C da Figura 18. Veja que ele é colocado nos endereços físicos
após o programa A.

Como vimos, o programa na memória principal possui seu código e seus


dados. O que não vimos, porém, é que a área de dados pode sempre ser
expandida. Essa expansão ocorre quando o programa realização alocação
dinâmica de memória, ou seja, o programa, durante sua execução, cria
novas variáveis para armazenar mais dados. Veremos a seguir como essa
expansão ocorre na memória.

14.2 Alocação de memória


O espaço que um programa ocupa na memória principal pode ser
expandido conforme as necessidades do programa, embora haja um
limite superior para essa expansão. Há dois modelos possíveis de
expansão de um programa, que dependem da implementação do SO e da
arquitetura do sistema.

Em um primeiro modelo, mais simples, o processo possui um trecho de


código e logo em seguida um trecho de dados que pode ser expandido
sequencialmente. Esse modelo foi o que estudamos nesta unidade, em que
tínhamos o código do programa e em seguida vários dados que ele utilizava.

No segundo modelo, cada processo possui uma pilha e uma heap.


A pilha guarda endereços de funções e variáveis locais como as vistas
anteriormente. A heap é uma área temporária para variáveis alocadas
dinamicamente, comuns em linguagens como a C. Dessa forma, cada
programa possui um trecho com seu código, um trecho com sua heap e
um trecho com sua pilha. Nesse cenário, a pilha e a heap se expandem
uma de encontro à outra. A Figura 19 mostra esses dois modelos de
alocação de memória para um processo.

www.esab.edu.br 88
Área para Pilha
expansão Área para
expansão
Em uso Heap
Código

Figura 19 – Visão de um programa na memória principal em


um modelo com uma ou duas áreas de expansão.
Fonte: Elaborada pelo autor (2013).

Independentemente do modelo utilizado, todo programa na memória


pode ser expandido. Além disso, novos programas podem ser executados.
De acordo com Tanenbaum (2010), a gerência de memória estudada
nesta unidade já seria suficiente se a memória principal sempre fosse
grande o bastante para armazenar todos os programas que o usuário
deseja executar simultaneamente. Entretanto, como já comentamos, isso
não ocorre em um cenário real.

Na próxima unidade, vamos nos aprofundar no gerenciamento de


memória e estudar como o SO faz para gerenciar a memória de forma
a permitir que todos os programas executem mesmo não havendo
memória suficiente.

Fórum
Caro estudante, dirija-se ao Ambiente Virtual de
Aprendizagem da instituição e participe do nosso
Fórum de discussão. Lá você poderá interagir com
seus colegas e com seu tutor de forma a ampliar,
por meio da interação, a construção do seu
conhecimento. Vamos lá?

www.esab.edu.br 89
Gerenciamento de memória –
15 parte 2
Objetivo
Apresentar técnicas mais avançadas de gerenciamento de memória,
introduzindo o conceito de memória virtual e o uso de MMU,
paginação e segmentação.

Na unidade anterior começamos a estudar mais a fundo o gerenciamento


de memória realizado pelo SO. Vimos que, para permitir que vários
programas ocupem a memória ao mesmo tempo, o SO cria a abstração
de um espaço de endereçamento virtual, onde cada programa fica livre
para usar os endereços que quiser. Porém, no momento da execução,
o SO converte endereços virtuais em endereços físicos, usando o
registrador-base como base de cada programa, permitindo que os
endereços corretos sejam utilizados.

Como apresentado, esse cenário resolve o problema do uso da memória


por múltiplos programas, mas não resolve o problema de a memória
principal não ser grande o suficiente para guardar o código e os dados de
todos os programas em execução.

Nesta unidade, começaremos a estudar as técnicas usadas pelo hardware


do computador e também pelo SO para solucionar esse problema.
Novamente basearemos nossos estudos no trabalho de Tanenbaum
(2010). De acordo com o autor, há duas técnicas úteis para gerenciar a
falta de espaço na memória: a troca de processos e o uso de memória
virtual. Ambas as técnicas geralmente se complementam e costumam ser
bastante usadas.

A troca de processos ou swapping é a ação de tirar um programa da


memória principal e salvá-lo em disco sem finalizar seu processo, mas
liberando espaço na memória para que outro programa comece a ser
executado. Quando o SO deseja colocar um novo programa na memória
e o espaço disponível dentro dela é insuficiente, o SO pode pegar todo

www.esab.edu.br 90
o espaço de endereçamento de um programa na memória e salvá-lo
em disco; em seguida, pode pegar o espaço de endereçamento do novo
programa e colocá-lo na memória. Essa operação é chamada de swap.

A Figura 20 mostra a operação de swap sendo realizada. A figura mostra a


memória principal e a memória secundária em três momentos distintos.
Em um primeiro momento, os programas 1 e 2 estão ocupando a memória
principal. Então, em um segundo momento, o programa 1 é removido
inteiramente da memória principal e salvo na memória secundária. No
terceiro momento apresentado na figura, um novo programa 3 é carregado
para a memória principal e sua execução é iniciada.
Área de swap da
Memória principal memória secundária
Programa 1 Programa 3
1
Programa 2

Programa 3
2
Programa 2 Programa 1

Programa 3
3
Programa 2 Programa 1

Figura 20 – Operação de swap de processos sendo realizada.


Fonte: Elaborada pelo autor (2013).

Para gerenciar o espaço de endereçamento de todos os programas na


memória e permitir um uso otimizado do recurso, o SO pode realizar
realocações, ou seja, pegar todos os dados de uma região e movê-los
para outra região da memória. Isso é útil em situações em que há espaço
suficiente na memória, porém esse espaço não é contíguo.

www.esab.edu.br 91
Antes da realocação Após a realocação
Programa 1 Programa 1

Programa 2
Programa 2
Programa 3
Programa 3 Programa 4
Programa 4 Programa 5

Figura 21 – Realocação de programas na memória principal com


objetivo de liberar espaço para novos programas.
Fonte: Elaborada pelo autor (2014).

É comum haver dois ou mais trechos livres na memória, como mostra


a Figura 21. Veja à esquerda que existem quatro programas na memória
principal, porém há espaços vazios entre eles. Esses espaços, porém, são
pequenos demais para armazenar um programa inteiro. Os programas
na memória podem então ser movidos para que dois ou mais trechos
livres pequenos se transformem em um grande trecho livre da memória,
permitindo que um novo programa seja carregado nesse espaço livre,
como ocorre com o Programa 5 da figura.

Para isso, o SO precisa gerenciar todos os espaços livres na memória


utilizando estruturas como tabelas ou listas que indicam em qual
endereço começa e termina cada área livre. Ao carregar um novo
programa para a memória, se há mais de um espaço livre, o SO também
precisa decidir em qual espaço o coloca. Para tanto, diversas políticas
podem ser usadas, como escolher o primeiro espaço que encontrar ou
escolher o menor espaço possível que seja suficiente, por exemplo.

O maior problema do swapping é que, atualmente, alguns programas


podem ocupar muito espaço, às vezes, chegando à casa dos gigabytes, e,
além disso, pode demorar vários segundos para que o SO realize o swap de
um programa desse tamanho, mesmo com as mais modernas tecnologias
de discos rígidos. Por isso, para complementar o swapping, costuma-se
usar outra técnica para gerenciar a memória: a memória virtual. Por ser
uma técnica importante, esse conceito será introduzido nesta unidade e
será a base para os estudos que realizaremos nas próximas unidades.

www.esab.edu.br 92
O conceito de memória virtual funciona de forma semelhante ao do
espaço de endereçamento virtual. De acordo com Tanenbaum (2010),
cada programa possui seu código, dados e seu espaço de endereçamento,
o qual pode ser expandido ou reduzido durante a execução do programa.
Esse espaço de endereçamento pode ser dividido em partes menores, as
quais chamamos de páginas. Cada página é um conjunto de endereços
contíguos na memória. O tamanho de uma página varia dependendo do
SO, mas em um mesmo SO, todas as páginas possuem o mesmo tamanho.

Um ponto importante a respeito dessas páginas é que nem todas


precisam estar na memória para o programa ser executado normalmente.
Por exemplo, páginas pouco usadas podem ficar guardadas em disco,
liberando mais espaço na memória principal. Quando algum endereço
precisa ser acessado e ele pertence a uma página que não está na memória
principal, essa página precisa ser carregada do disco para a memória,
assim, o endereço pode ser acessado corretamente.

Quando usamos a memória virtual, a conversão de endereços virtuais


em endereços físicos se torna mais complexa, pois não basta somarmos
cada endereço ao registrador-base do programa. Para isso, usamos o que
chamamos de unidade de gerenciamento de memória, ou MMU, como
veremos a seguir.

15.1 Unidade de gerenciamento de memória (MMU)


A MMU é um componente de hardware que fica entre o processador
e a memória e é a responsável por transformar endereços virtuais em
endereços físicos e vice-versa.

A MMU conecta o processador (responsável pela execução de cada


instrução) à memória, que armazena todas as instruções e os dados com
os quais elas trabalham. O processador só conhece os endereços virtuais e
o espaço de endereçamento virtual do programa. A memória, no entanto,
possui endereços físicos. Essa conversão é realizada pela MMU a cada
acesso à memória.

www.esab.edu.br 93
Quando o processador está executando uma instrução e deseja acessar
um dado, por exemplo, no endereço virtual 10, ele pede para a memória
principal fornecer o dado que está no endereço 10. Porém, o processador
não sabe que o endereço 10 na verdade é apenas virtual, não físico. A
MMU então intercepta o pedido do processador, converte o endereço
10 no verdadeiro endereço físico onde está o dado e finalmente repassa o
pedido para a memória principal, que acessa o dado no local correto.

Fazendo uso da MMU, o SO consegue gerenciar a memória virtual, por


meio de uma técnica chamada de paginação, como veremos a seguir.

15.2 Paginação
A técnica de paginação será introduzida nesta unidade e estudada em
detalhes na próxima. De forma geral, o espaço de endereçamento de
um programa é dividido em páginas. De acordo com Tanenbaum
(2010), a memória física é dividida em diversas molduras de páginas,
que são do mesmo tamanho das páginas e servem para armazenar as
páginas dos programas. A Figura 22 a seguir mostra a memória física
de um computador dividida em molduras de página e o espaço de
endereçamento de um programa sendo dividido em páginas.

Memória física e Programa dividido


molduras de página em páginas

Figura 22 – Memória física dividida em molduras de páginas e um programa dividido em páginas.


Fonte: Elaborada pelo autor (2013).

Quando um programa é carregado para a memória, suas páginas são


colocadas em molduras de páginas da memória física. Porém, nem todas

www.esab.edu.br 94
as páginas de um programa precisam ser colocadas na memória; apenas
aquelas que serão usadas no início. Isso permite que o programa utilize
menos memória, já que as páginas não usadas não ficam na memória.

O hardware da MMU gerencia quais páginas estão na memória física e


quais não estão. Para isso, a MMU possui uma tabela de páginas, usada
na conversão de endereços. Essa tabela também possui um bit extra
para cada página, o qual possui um valor se a página estiver presente
na memória física e o valor inverso se não estiver, ou seja, se o valor 1
significa que a página está presente, o valor 0 deve significar que a página
não está presente.

Quando uma instrução em execução pela UCP tenta acessar um


endereço na memória que faz parte de uma página presente na memória
física, a MMU converte o endereço em um endereço físico e o acesso à
memória é realizado normalmente. Porém, quando a UCP tenta acessar
um endereço de uma página que não está presente na memória, ocorre
o que chamamos de falta de página. Nesse momento, o SO é avisado
de que a página requerida não se encontra na memória. De forma
semelhante ao que ocorre no swapping, o SO escolhe uma moldura de
página pouco usada e salva seu valor no disco. Em seguida, ele carrega
para a memória a página requerida pela UCP e pede à UCP que tente
executar novamente a instrução que causou a falta de página.

Outra técnica usada para prover um melhor uso da memória se chama


segmentação, que será introduzida a seguir e estudada em mais detalhes
na unidade 17.

15.3 Segmentação
Embora com uso da paginação seja possível dividir um único espaço de
endereçamento em diversas páginas e carregá-las na memória conforme
a necessidade do programa, ainda assim, há casos em que a existência de
um único espaço de endereçamento pode causar problemas.

www.esab.edu.br 95
Quando um programa é compilado, o espaço de endereçamento dele
é preenchido por diversos dados diferentes. Há um espaço para as
instruções compiladas e outro espaço para a pilha de chamadas do
programa, onde ficarão guardados dados, como endereços de funções,
variáveis locais do programa, entre outros tipos de estruturas que são
armazenados no espaço de endereçamento do programa.

Durante a compilação, porém, pode acontecer de uma dessas áreas


atingir seu limite de expansão, por exemplo, em programas que
possuem muitas variáveis. Entretanto, pode ser que ainda haja espaço
sobrando em outros trechos do espaço de endereçamento. Nesse caso,
é interessante que essa divisão do espaço entre essas diferentes áreas do
espaço de endereçamento seja mais flexível.

Para resolver esse problema, é possível permitir que um mesmo


programa possua diversos espaços de endereçamento, um para cada
estrutura do programa que possa sofrer expansões. Cada um desses
espaços de endereçamento é chamado de segmento. A separação
do espaço de endereçamento em segmentos é uma técnica chamada
de segmentação. De acordo com Tanenbaum (2010), a principal
vantagem da segmentação é permitir que partes distintas de um mesmo
programa, como código e dados, pertençam a espaços de endereçamento
independentes, com áreas de expansão independentes. Na unidade 17
estudaremos a segmentação mais detalhadamente.

Assim, terminamos a unidade 15. Vimos nesta unidade o que é memória


virtual, fomos introduzidos a um novo componente de hardware, a
MMU, e vimos o que são a paginação e a segmentação. Na próxima
unidade vamos estudar a fundo a paginação e suas características.

www.esab.edu.br 96
16 Paginação

Objetivo
Descrever com mais detalhes o conceito de paginação.

A memória virtual foi um dos principais conceitos introduzidos na


unidade anterior. Pudemos entender a motivação para usá-la e estudamos
a técnica de paginação, a qual permite que a memória usada por todos os
programas abertos seja maior que a memória física que realmente existe
no computador.

Estudamos, na unidade anterior, que a MMU é um componente de


hardware que fica entre a UCP e a memória e é a responsável por
converter endereços virtuais usados pelos programas em endereços físicos
usados pela memória e vice-versa. Essa MMU mantém uma estrutura
que indica quais páginas de quais programas estão na memória e quais
não estão. Dessa forma, quando o processador tenta acessar algum
endereço pertencente a uma página que não está na memória, a MMU
detecta isso e informa ao SO, que é responsável por buscar a página do
disco e colocá-la na memória e pedir para ao processador que execute,
novamente, a instrução que dava acesso à memória.

Todo esse mecanismo se chama paginação de memória virtual, e nesta


unidade iremos entender mais a fundo o funcionamento dessa técnica.
Usaremos como base para os nossos estudos o trabalho de Tanenbaum
(2010) e o de Silberschatz, Galvin e Gagne (2001).

16.1 Como funciona a paginação


A paginação consiste na divisão do espaço de endereçamento de um
programa em páginas. Cada página deve ter o mesmo tamanho e esse
tamanho nunca muda, embora cada SO possa escolher o tamanho de
página que usará. Os SOs costumam usar tamanho de página desde 512
bytes até 64 KB.

www.esab.edu.br 97
Para reduzir o uso da memória, é possível mantê-la com apenas algumas
páginas do programa e deixar outras salvas em disco. Uma MMU é
usada para manter um controle a respeito de quais páginas estão na
memória e quais não estão. Os programas são criados com um espaço de
endereçamento virtual no qual o programa acessa seus dados e código
sem saber como eles estão armazenados na memória. Assim, a MMU
converte endereços virtuais de acesso em endereços físicos. A Figura 23,
de Tanenbaum (2010), mostra esse mapeamento de endereços virtuais
em endereços físicos.
Espaço de
endereçamento
virtual
60 K - 64 K X
56 K - 60 K X Página virtual
52 K - 56 K X
48 K - 52 K X
44 K - 48 K 7
40 K - 44 K X Endereço
36 K - 40 K 5 de memória
física
32 K - 36 K X
28 K - 32 K X 28 K - 32 K
24 K - 28 K X 24 K - 28 K
20 K - 24 K 3 20 K - 24 K
16 K - 20 K 4 16 K - 20 K
12 K - 16 K 0 12 K - 16 K
8 K - 12 K 6 8 K - 12 K
4K-8K 1 4K-8K
0K-4K 2 0K-4K
Estrutura da página
Figura 23 – Exemplo de relação entre endereços virtuais usados pela UCP e endereços físicos da memória.
Fonte: Tanenbaum (2010, p. 116).

À esquerda da Figura 23 temos o espaço de endereçamento completo


do programa, que no caso possui 64 KB de tamanho. A memória física,
mostrada à direita, porém, possui apenas 32 KB de espaço. À esquerda
temos endereços virtuais e à direita endereços físicos. Devido ao espaço
físico ser menor, várias páginas do espaço de endereçamento virtual não

www.esab.edu.br 98
caberão na memória física. As páginas que estiverem na memória física
estarão conectadas por uma flecha que indica a posição exata da página
na memória.

Na Figura 23, cada página possui um número, o qual indica qual


moldura de página da memória física possui aquela página. As páginas
que possuem um X não estão na memória principal. Note que nesse
exemplo cada página possui 4 KB de tamanho.

Você também pode ver, por exemplo, que o bloco de endereços virtuais
entre o endereço 44 K – 48 K está entre os endereços 28 K – 32 K da
memória física. Isso significa que quando o programa tenta acessar o
endereço 44 K, a MMU converte o acesso para o endereço 28 K, e esse
endereço é acessado na memória principal.

As setas da figura mostram que não há uma relação aparente entre as


posições de uma página no espaço de endereçamento virtual e físico. Essa
relação, na verdade, é definida pela MMU por meio da sua tabela de
páginas. Veremos mais sobre esse assunto a seguir. Acompanhe!

16.2 Tabelas de páginas


De acordo com Silberschatz, Galvin e Gagne (2001), a tabela de páginas,
por possuir uma linha para cada página, pode se tornar uma estrutura
muito longa em sistemas em que o espaço de endereçamento dos
programas é grande. Por exemplo, em um sistema com endereços de 32
bits, considerando cada página como tendo 4 KB, a tabela de páginas
precisaria ter cerca de um milhão de linhas. Considerando que cada linha
precisaria ter pelo menos 4 bytes, o tamanho total da tabela seria de, no
mínimo, 4 MB para cada processo.

Ainda de acordo com Silberschatz, Galvin e Gagne (2001), existem várias


soluções para esse problema, sendo a divisão da tabela de páginas em dois
níveis a mais simples delas. Nesse cenário, a própria tabela de páginas
também é paginada. Primeiramente, acessa-se o nível mais exterior,
chamado de tabela de página exterior. Essa tabela indica em qual tabela de
páginas do segundo nível está a página do endereço sendo acessada. Ela é
acessada, e a página em questão é verificada. A Figura 24 ilustra esse cenário.

www.esab.edu.br 99
0
1
..
.
1
..
.
500 100
..
. ..
.
100 500
.. ..
.. . .
.
708
.. 708 ..
. .
900
tabela de 929
.. ..
página . .
exterior 900 929
página de ..
.
tabela de memória
página
tabelas de
página
Figura 24 – Exemplo de tabela de páginas de dois níveis (modelo usado em
sistemas com espaço de endereçamento extenso).
Fonte: Adaptada de Silberschatz, Galvin e Gagne (2001).

Note que a tabela exterior, à esquerda, apenas indica qual é a verdadeira


tabela de página que possui a página que queremos acessar. No segundo
nível, mostrado ao centro da figura, temos diversas tabelas de páginas,
cada uma em uma página. Por fim, cada uma dessas tabelas de páginas
está mapeada em uma moldura de página da memória principal, como
mostrado à direita. Utilizar esse mecanismo ajuda a reduzir o espaço
necessário para armazenar tabelas de páginas. A seguir veremos detalhes a
respeito da implementação de sistemas de paginação.

16.3 Implementação de paginação


Sistemas de paginação enfrentam sempre dois desafios. O primeiro
deles é que a conversão de endereços virtuais para endereços físicos deve
ser rápida, pois acessos à memória são muito comuns e isso influencia
diretamente o desempenho de todo o computador. Além disso, se o
espaço de endereçamento for grande, a tabela de páginas será grande

www.esab.edu.br 100
também. Esse segundo desafio já foi estudado nesta unidade, na qual
mostramos que uma das formas de solucioná-lo é dividindo a tabela de
páginas em dois níveis.

Esses desafios indicam que o desempenho da tabela de páginas não


pode ser negligenciado. De acordo com Tanenbaum (2010), a solução
para o problema do desempenho é utilizar um buffer para tradução
de endereços (TLB, do inglês translation lookaside buffer), também
chamado, às vezes, de memória associativa.

A TLB funciona como uma cache da tabela de páginas, ou seja, as páginas


mais acessadas da tabela de páginas são mantidas nessa estrutura separada
da TLB, onde seu acesso pode ser realizado de forma muito mais rápida.
Se a entrada na TLB não existir, ela é procurada na tabela de páginas
em si. A TLB é geralmente implementada como um componente de
hardware dentro da própria MMU e, na maioria das vezes, possui pouco
espaço para entradas da tabela de páginas (raramente mais que 64 KB).

Processador Barramento

UCP MMU Memória


TLB

Figura 25 – Localização da MMU e da TLB na estrutura de um computador.


Fonte: Elaborada pelo autor (2013).

A Figura 25 apresenta uma versão ampliada da Figura 20, agora


mostrando, também, a localização da TLB dentro do computador.

Outro aspecto importante ao implementar a paginação é a política


de substituição de páginas. Quais páginas substituímos quando
vamos colocar uma nova página na memória? Essa questão é bastante
importante, pois influencia diretamente o desempenho do sistema de
paginação. A resposta para essa pergunta será estudada na unidade 18,
quando veremos algoritmos de substituição de páginas.

www.esab.edu.br 101
Estudo complementar
Nesta unidade você pôde conhecer em detalhes
a técnica de paginação. Para complementar
seus estudos e entender melhor os conceitos
estudados, faça uma leitura do material sobre
paginação disponível clicando aqui.

Terminamos aqui mais uma unidade sobre o gerenciamento de memória


realizado pelo SO. Vimos em mais detalhes como funciona a paginação e
suas características de implementação. Na próxima unidade vamos estudar
em detalhes outra técnica de gerenciamento de memória: a segmentação.

Atividade
Chegou a hora de você testar seus conhecimentos
em relação às unidades 9 a 16. Para isso, dirija-se ao
Ambiente Virtual de Aprendizagem (AVA) e responda
às questões. Além de revisar o conteúdo, você estará
se preparando para a prova. Bom trabalho!

www.esab.edu.br 102
17 Segmentação
Objetivo
Aprofundar o conceito a respeito do uso de segmentação e sua
relação com o conceito de paginação.

Na unidade 15 introduzimos os conceitos de paginação e segmentação.


Vimos que ambas servem para resolver problemas semelhantes,
melhorando a gerência de memória dos computadores. Na unidade
anterior pudemos estudar com mais detalhes a técnica de paginação, em
que a memória virtual é dividida em páginas, eliminando a necessidade
de todo o espaço de endereçamento do programa estar na memória ao
mesmo tempo. Na paginação, apenas as páginas em uso precisam estar na
memória, e quase nunca o espaço de endereçamento inteiro do programa
estará em uso em um mesmo momento.

Nesta unidade, vamos estudar em detalhes a outra técnica, a de


segmentação. Assim, como vimos na unidade 15, essa técnica aborda
outros problemas da gerência de memória e pode ser vista como um
complemento à técnica de paginação. Por isso, ao fim dessa unidade,
vamos estudar como seria um cenário em que a gerência de memória
utilizaria, ao mesmo tempo, as técnicas de paginação e segmentação.
Usaremos o trabalho de Tanenbaum (2010) para fundamentar nossos
estudos. Por enquanto, vamos começar entendendo bem como funciona
a segmentação.

17.1 Como funciona a segmentação?


Para compreender a segmentação, vamos primeiro desconsiderar
a técnica de paginação e tratar o espaço de endereçamento de um
programa como uma coisa só, presente 100% na memória. O espaço de
endereçamento é definido na compilação do programa e cada trecho do
espaço é reservado a um tipo de informação. Há uma parte reservada
ao código compilado do programa e outra parte reservada para a pilha

www.esab.edu.br 103
de chamadas, que guardam endereços de funções e variáveis locais do
programa etc. Cada uma dessas áreas reservadas possui tamanho máximo
fixo, o que pode ser um problema se o programa tiver muitas variáveis
ou um código muito extenso. Essas áreas do espaço de endereçamento
podem se expandir de forma imprevisível; uma dessas áreas de tamanho
reservado pode atingir seu limite de espaço, enquanto outras áreas ainda
o possuem. É preciso, então, balancear melhor o uso do espaço de
endereçamento do programa. A solução para isso está no uso da técnica
de segmentação.

A técnica de segmentação se fundamenta no fato de que há diferentes


tipos de dados no espaço de endereçamento de um programa. Embora,
em geral, todo o espaço possa ser visto como uma grande lista de dados
binários, há partes com significados diferentes, e o mais importante é
que cada uma dessas partes se expande ou se contrai de forma diferente
durante a compilação do programa.

Para resolver esse problema, podemos dividir o espaço de endereçamento


do programa, desde a fase de compilação, em vários espaços de
endereçamento. Nesse caso, cada um desses espaços, chamado segmento,
seria responsável por armazenar dados de um tipo. Teríamos um
segmento para o código do programa, também chamado de texto-fonte,
um segmento para constantes do programa etc. A Figura 26 mostra
como poderia ser essa divisão.

www.esab.edu.br 104
20 K

16 K 16 K

12 K 12 K 12 K 12 K
Tabela de
símbolos
8K 8K 8K Árvore 8K
sintática
Texto-fonte Pilha de
chamada
4K 4K 4K 4K

Constantes
0K 0K 0K 0K 0K
Segmento Segmento Segmento Segmento Segmento
0 1 2 3 4
Figura 26 – Exemplo de separação de um espaço de endereçamento
em segmentos por meio da técnica de segmentação.
Fonte: Tanenbaum (2010, p. 145).

Veja que na Figura 26 existem cinco segmentos, ou seja, cinco espaços de


endereçamento diferentes. Eles são independentes e, quando o programa
for executado, também poderão ser colocados na memória em locais
bastante diferentes. Isso permite que todos sofram uma expansão sem
afetar os outros, desde que o espaço total do programa não atinja o limite
do espaço de endereçamento definido para um único programa.

Na Figura 26, a tabela de símbolos do programa é uma tabela que define


todas as variáveis do programa, seus nomes e suas informações relevantes. A
árvore sintática é uma estrutura que contém a análise sintática realizada pelo
compilador, tema estudado brevemente nas disciplinas de Programação I e
II. A pilha de chamadas, como já comentamos, possui informações sobre a
função que está sendo executada atualmente. Em outras palavras, ela possui
as variáveis locais usadas na função, o endereço da função e o endereço
da linha de código que realizou a chamada da função. Veremos a seguir
detalhes a respeito de como é implementada a segmentação.

www.esab.edu.br 105
17.2 Implementação de segmentação
De acordo com Tanenbaum (2010), a técnica de segmentação afeta
a vida de um programa de computador desde muito antes de ele ser
executado. Como vimos anteriormente, a própria compilação do
programa é totalmente afetada pela segmentação. Isso significa que a
segmentação não é simplesmente uma técnica usada para melhorar o
gerenciamento da memória.

A paginação não influencia os programadores que criaram o programa,


ou seja, um mesmo programa compilado pode ser executado em um
computador com paginação e sem paginação, e em nenhum momento
o programador precisa estar ciente da paginação que está sendo realizada
pelo computador.

A segmentação, por outro lado, afeta até mesmo os programadores e a forma


como o compilador trabalha. Por exemplo, um segmento pode receber
permissões de acesso diferentes de outro. Nesse caso, os programadores
podem proteger certos trechos do espaço de endereçamento, conforme a
natureza dos dados que lá estiverem sendo armazenados. A um trecho de
código executável, por exemplo, pode ser dada a permissão de apenas ser
executado, de forma a proibir tentativas de leitura ou escrita.

Na segmentação, de forma semelhante ao que ocorre na paginação, cada


programa possui uma tabela de segmentos, que também informa quais
segmentos estão na memória física e quais não estão.

Note que a segmentação, embora resolva problemas complementares à


paginação, possui alguns conflitos com o conceito de paginação. Porém, é
possível utilizar as duas técnicas em conjunto, como veremos logo a seguir.

17.3 Segmentação com paginação


O uso da segmentação em conjunto com a paginação é útil, pois mesmo
que o espaço de endereçamento de um programa esteja dividido em
vários segmentos, os segmentos são independentes. Além disso, pode
acontecer de alguns serem grandes demais para mantê-los na memória
física em sua totalidade ao mesmo tempo.

www.esab.edu.br 106
O que se costuma fazer então, de forma geral, é dividir cada segmento
de um programa em um conjunto de blocos contíguos de endereços de
memória chamados de páginas, ou seja, aplica-se a técnica de paginação
separadamente para cada segmento.

Cada programa possui uma tabela de segmentos que indica se o


segmento está na memória. Com o uso de paginação, essa tabela indicará
que o segmento está na memória se pelo menos uma página dele estiver.
Sempre que isso ocorre, a tabela de páginas daquele segmento também
estará na memória física.

Assim, a tabela de segmentos do programa costuma informar em qual


endereço está a tabela de páginas de cada segmento, permitindo que
após encontrar o segmento, o mecanismo de gerência de memória possa,
facilmente, encontrar a página desejada.

Quase a totalidade dos computadores de mesa e notebooks modernos


possuem hardware e SO que utilizam as técnicas de segmentação
e paginação em conjunto. Terminamos assim esta unidade sobre
segmentação. Na próxima unidade, terminaremos nossos estudos a
respeito do gerenciamento de memória. Resumiremos os principais
conceitos vistos e estudaremos alguns aspectos extras a respeito da
memória virtual.

Saiba mais
Agora que você já estudou em detalhes
como funcionam as técnicas de paginação e
segmentação, faça uma leitura do material
disponível clicando aqui que irá complementar
seus estudos e proporcionar maior entendimento
sobre os conceitos que talvez não tenham ficado
totalmente claros.

www.esab.edu.br 107
18 Memória virtual
Objetivo
Apresentar o conceito de memória virtual e sua utilidade tendo em
vista as características de hardware do computador.

Nas últimas cinco unidades estudamos sobre o gerenciamento de


memória realizado pelo SO com auxílio do hardware do computador.
Vimos que a memória é um recurso espacial em que cada programa
recebe uma fatia do todo (que consiste no seu espaço de endereçamento)
e pode usá-la durante sua execução. Vimos também que esse recurso
é muito limitado e, na maioria das vezes, a soma da quantidade de
memória usada por todos os programas abertos ultrapassa a quantidade
de memória disponível no computador.

Para resolver esse problema, é preciso realizar o gerenciamento do


uso da memória, e vários componentes de hardware existem com a
finalidade de auxiliar nesse gerenciamento, como é o caso da MMU
e da TLB, estudados anteriormente. Nesta unidade vamos resumir os
principais conceitos vistos nas últimas unidades e também apresentar
alguns conceitos novos sobre o gerenciamento de memória. Para tal,
vamos iniciar revisando o que é o gerenciamento de memória, tendo
Silberschatz, Galvin e Gagne (2001) e Tanenbaum (2010) como base de
nossos estudos.

18.1 Gerenciamento de memória virtual


O principal conceito referente ao gerenciamento de memória é o
uso de memória virtual, o que relaciona-se ao conceito de espaço de
endereçamento virtual, ou seja, o espaço de endereçamento que o
próprio programa enxerga, já que o espaço de endereçamento físico é
escondido do programa. O espaço de endereçamento virtual começa
no endereço 0 e possui espaço suficiente para todo o código e dados do
programa. Assim, é um espaço de endereçamento ideal.

www.esab.edu.br 108
No entanto, a realidade é um pouco diferente, já que o espaço de
endereçamento físico do programa não começa, necessariamente, no
endereço 0, já que o endereço 0 pode já estar sendo usado por outro
processo no momento em que o programa é carregado para a memória.
Além disso, o espaço de endereçamento física é limitado, e é função do
SO e do hardware do computador esconder isso do usuário e permitir
que ele trabalhe como se só houvesse o espaço de endereçamento virtual.
Para o usuário, todo o espaço de endereçamento faz parte da memória
física. Porém, o uso de memória virtual com técnicas como paginação
e segmentação permite que esse espaço de endereçamento seja dividido
em unidades menores, permitindo que cada uma dessas unidades só
esteja na memória física quando for estritamente necessária. Vimos, na
unidade anterior, que as técnicas de paginação e segmentação podem ser
complementares. Nesse caso, o espaço de endereçamento do programa é
dividido em segmentos e cada segmento é dividido em páginas.

A técnica de paginação divide o espaço de endereçamento em páginas


de mesmo tamanho. Em alguns sistemas, essas páginas têm 512 bytes,
e em outros podem ser tão grandes quanto 64 KB. Durante a execução
do programa nem todas as suas páginas precisam estar na memória para
que seja executado. Se em algum momento o programa deseja acessar
um endereço de memória que faz parte de uma página que não está na
memória, o SO busca essa página secundária e a coloca na memória
principal, permitindo que o programa continue sua execução.

Um problema que pode surgir a partir do uso dessa técnica é o que


os autores Tanenbaum (2010) e Silberschatz, Galvin e Gagne (2001)
chamam de fragmentação interna. Digamos que cada página possua 4
KB, o que é bastante comum. Vamos supor que criamos um programa
e o espaço de endereçamento dele tem apenas 3 KB. Considerando que
cada página tem 4 KB, não é possível termos páginas com tamanho
de 3 KB. Nesse caso, o espaço de endereçamento do programa é
colocado em uma página de 4 KB, sendo que o 1 KB restante fica
inutilizado e é, consequentemente, desperdiçado. Esse problema é
chamado de fragmentação interna e não tem como ser evitado, embora
possa ser bastante reduzido se os projetistas do computador definirem
um bom tamanho de página. Como afirmamos, é possível encontrar
computadores com páginas desde 512 bytes até 64 KB, contudo o
tamanho de página mais comum é de 4 KB.

www.esab.edu.br 109
A técnica de segmentação é semelhante, mas resolve outros
desafios do gerenciamento de memória. Na segmentação, o espaço
de endereçamento do programa é dividido em diversos espaços de
endereçamento independentes, chamados segmentos. Como cada
segmento não precisa ter o mesmo tamanho que os outros, não sofremos
com o problema da fragmentação interna.

Não obstante, sofremos com outro problema: supondo que a memória


física possua 12 KB de espaço e temos um programa com 11 KB de
espaço. Se usássemos paginação, teríamos três páginas de 4 KB capazes de
armazenar 12 KB de dados. Como temos apenas 11 KB de dados, uma
das páginas do programa sofreria de fragmentação interna. Porém, no
caso da segmentação, os espaços de endereçamento possuem exatamente
o espaço de que precisam. Digamos que são colocados na memória,
então, dois segmentos, um com 7 KB e o outro com 4 KB. Assim, 11
KB dos 12 disponíveis serão ocupados pelo programa. No entanto, note
que esse 1 KB que sobrou ainda está livre para outros programas. Mas
que outro programa caberia em 1 KB? Esse 1 KB continuaria sendo
desperdiçado, pois provavelmente nenhum segmento de programa
caberia em 1 KB. Esse fenômeno caracteriza o que chamamos de
fragmentação externa, pois a memória desperdiçada fica externa ao
programa. A seguir revisaremos a técnica de swapping, também muito
usada quando a utilização da memória principal chega perto do seu
limite e precisamos remover dados da memória.

18.2 Swapping
A técnica de swapping é uma forma primitiva de gerenciamento de
memória, embora hoje em dia ainda seja usada em conjunto com a
paginação e a segmentação. Conforme Tanenbaum (2010), o swapping
consiste simplesmente em pegar um programa que está na memória física
e tirá-lo de lá, permitindo que outro programa possa ser carregado na
memória. Essa troca de processos é uma forma bem simples de permitir
que a memória de todos os programas em execução ultrapasse o tamanho
da memória física.

www.esab.edu.br 110
Porém, com o uso de paginação o swapping passa a trocar páginas entre
a memória principal e a secundária em vez de trocar processos inteiros.
Essa troca de páginas, porém, precisa ser realizada de forma inteligente.
Se formos tirar uma página da memória principal, é bom que seja uma
página pouco útil. Por exemplo, apenas pioraremos o desempenho do
sistema se tirarmos da memória uma página que logo em seguida se
tornará necessária.

É difícil prever esses fenômenos, mas é possível fazer estimativas, e


existem vários algoritmos que atacam esse problema de diversas formas,
como veremos a seguir.

18.3 Algoritmos de substituição de páginas


Escolher qual página substituir pela que será carregada é uma tarefa
difícil e diversos algoritmos foram criados ao longo dos anos para tentar
resolver esse problema. Um algoritmo perfeito, como Tanenbaum (2010)
coloca, é fácil de descrever, mas impossível de implementar. De acordo
com o algoritmo ótimo, cada página na memória saberia, de alguma
forma, quando ela seria utilizada novamente. Dessa forma, é simples
decidir qual página substituir: podemos escolher aquela que demorará
mais tempo para ser usada novamente.

Uma versão simples e factível desse algoritmo é o da substituição de


página não usada recentemente (NRU). Cada página possui um bit
que informa se ela foi usada recentemente ou não. Quando é preciso
substituir uma página, escolhe-se aleatoriamente uma das que não foram
usadas recentemente. Esse bit é zerado periodicamente, para que as
páginas que foram usadas há mais tempo sejam diferenciadas das que
foram usadas há pouco tempo. De acordo com Tanenbaum (2010), esse
algoritmo fornece um desempenho que, dependendo do cenário, pode
ser adequado.

www.esab.edu.br 111
Outro algoritmo conhecido é o de “Primeiro a entrar, primeiro a sair”,
conhecido pela sigla FIFO, do inglês First-in, First-out. De acordo com
esse algoritmo, a página a ser removida é simplesmente a que esteja
na memória há mais tempo. Outro algoritmo, chamado de “segunda
chance”, mistura os dois algoritmos anteriores, pois tenta substituir a
página mais antiga, desde que ela não tenha sido usada recentemente.

Há um algoritmo que exclui a página menos usada e também outros que


se baseiam em remover uma página aleatoriamente, embora seguindo
algum raciocínio lógico.

Terminamos aqui o nosso estudo a respeito do gerenciamento de


memória. Conhecemos todos os desafios enfrentados pelos projetistas de
computadores e de SOs em termos do uso de memória e pudemos ver as
mais diversas técnicas para resolver os problemas da área.

Na próxima unidade mudamos novamente de tópico, passando a tratar


do gerenciamento de arquivos e diretórios, realizado pelo SO por meio
de seu sistema de arquivos. Até lá!

Estudo complementar
Agora que você já estudou o que é memória virtual
e como funciona o espaço de endereçamento dos
programas, leia o material disponível clicando
aqui para saber mais sobre esses tópicos.

www.esab.edu.br 112
Resumo

Nas últimas seis unidades estudamos o gerenciamento de memória


realizado pelo SO com a ajuda de diversos componentes de hardware do
computador, como a MMU e a TLB.

Estudamos, inicialmente, o que é o espaço de endereçamento de um


programa e para que ele serve. Vimos que cada programa precisa dividir
os recursos de memória com todos os outros programas e que cada
programa, individualmente, não tem como saber quais outros estarão na
memória no momento de sua execução. Portanto, os endereços onde ele
guarda seus dados não podem depender dos outros programas.

Para resolver esse problema, usa-se o conceito de memória virtual, em


que cada programa possui a memória e usa os endereços desejados sem
limitações por parte dos outros programas. Durante a execução, porém,
o SO e o hardware do computador tratam de adequar o espaço de
endereçamento do programa ao espaço que ele deve ocupar na memória
física, sem prejudicar seu desempenho.

Técnicas como paginação, segmentação, swapping etc., surgiram


para resolver todos esses desafios do gerenciamento de memória.
Computadores modernos possuem sistemas de gerenciamento de
memória em que cada programa possui vários espaços de endereçamento
chamados de segmentos. Assim, cada segmento é dividido em diversas
páginas, as quais podem ser colocadas na memória física ou salvas em
disco durante a execução do programa, de forma a permitir que páginas
de outros programas sejam carregadas para a memória física.

Nas últimas seis unidades pudemos entender como funcionam todas


essas técnicas e, ao mesmo tempo, compreender seus defeitos e os
efeitos colaterais acarretados para os programas, como a ocorrência de
fragmentação interna ou externa.

www.esab.edu.br 113
Nas próximas unidades mudaremos de tópico, passando a estudar os
sistemas de arquivos e o gerenciamento da memória secundária.

www.esab.edu.br 114
19 Introdução a sistemas de arquivos
Objetivo
Apresentar o que são sistemas de arquivos e o que são arquivos e
diretórios.

Nas últimas unidades estudamos a respeito do gerenciamento de


memória, vimos como o recurso de memória RAM é utilizado pelos
programas e como o SO realiza o gerenciamento desse recurso,
possibilitando que diversos programas sejam utilizados ao mesmo tempo.

Como vimos na unidade 4, a memória RAM, ou memória principal, é


uma memória volátil, e todo computador precisa ter pelo menos uma
memória volátil. Apesar dessa modalidade de memória perder todos os
seus dados quando é desligada, é um tipo muito mais rápido que o tipo
não volátil. Por isso, a memória volátil serve para armazenar os dados dos
programas enquanto eles estão sendo executados, pois é o momento em
que eles serão mais usados.

A memória não volátil, geralmente vista como o disco rígido do


computador ou memória secundária, é mais lenta, porém seus dados
permanecem mesmo quando ela é desligada. Essa memória é usada para
armazenar todos os programas e dados do usuário do computador.

De um modo geral, a memória secundária funciona de forma bem


parecida com a memória principal. Nesta e na próxima unidade,
estudaremos o que são arquivos e diretórios e qual é a relação deles com a
memória secundária do computador. Veremos como os programas fazem
uso desses arquivos e como o SO faz para gerenciar a utilização desse
recurso por parte de todos os programas. Para isso, fundamentaremos
nossos estudos no trabalho de Tanenbaum (2010) e Silberschatz, Galvin
e Gagne (2001).

www.esab.edu.br 115
De acordo com Silberschatz, Galvin e Gagne (2001), as memórias não
voláteis podem ser implementadas de diversas formas, não apenas como
discos rígidos. Há memórias não voláteis que não possuem discos, como
é o caso dos populares pen drives. Dessa forma, cada memória não volátil
que houver no computador precisaria ser usada de forma diferente,
conforme sua implementação. Por exemplo, a ação de buscar um dado
armazenado em um disco é realizada de forma bastante diferente da
busca por um dado em uma memória Flash e isso deveria refletir na
forma com que os programas usam esses componentes.

Outra alternativa seria abstrairmos o conceito de memória não volátil para


permitir que qualquer memória não volátil seja usada da mesma forma,
independentemente da sua implementação, e é isso que fazemos na
prática. O SO é o responsável por criar essa abstração. Graças a ele, toda
memória secundária pode ser tratada como uma grande lista de endereços
de memória, cada uma com espaço para armazenar um byte de dados.

Porém, além dessa abstração, é preciso haver uma organização dos


dados, pois diversos programas de computador podem querer usar a
memória secundária para armazenar dados deles próprios. Além disso,
computadores podem ter mais de um usuário, cada um com seus
próprios programas e dados.

Com vários programas e usuários querendo usar a memória secundária,


surgem algumas questões. Como descreve Tanenbaum (2010), uma delas
consiste em definir em qual local da memória colocar um novo dado, ou
seja, como saber quais locais da memória estão livres. A segunda questão
é como encontrar uma informação que foi armazenada anteriormente
na memória. Por fim, devemos nos questionar sobre como seria possível
impedir que um usuário tenha acesso aos dados de outros usuários.

Para responder a essas perguntas, veremos que, assim como o SO cria a


abstração de processo para gerenciar o uso do processador e a abstração
de espaço de endereçamento virtual para gerenciar o uso da memória
principal, ele também cria uma abstração para gerenciar o uso da
memória secundária. Como veremos a seguir, essa abstração é chamada
de arquivos.

www.esab.edu.br 116
19.1 Arquivos
De acordo com Silberschatz, Galvin e Gagne (2001), um arquivo é
um conjunto de dados que possui um nome e fica armazenado na
memória secundária. Esse conjunto geralmente possui um cabeçalho
que o descreve. Do ponto de vista de quem está utilizando o sistema
de arquivos, um arquivo é a menor unidade lógica possível de
armazenamento de dados na memória secundária, ou seja, não existe
meio arquivo.

O conceito de arquivo é muito genérico, pois um arquivo pode ter


qualquer forma possível e servir para qualquer finalidade. Podemos
considerar dois tipos de arquivos: os executáveis, que possuem código
e dados de programas; e os arquivos de dados, que podem armazenar
textos, imagens e outros tipos de mídias, como músicas e vídeos. É
importante destacar que a memória secundária pode possuir milhares ou
milhões de arquivos, todos independentes uns dos outros. Isso é possível,
pois todos os arquivos são gerenciados pelo SO, e é esse gerenciamento
que responde aos questionamentos de Tanenbaum (2010) levantados na
introdução desta unidade.

Como mencionado em unidades anteriores, o SO possui diversos


componentes, e o responsável por realizar o gerenciamento dos
arquivos no computador se chama sistema de arquivos. De acordo com
Tanenbaum (2010), o sistema de arquivos é o responsável por definir
como os arquivos no computador são estruturados, nomeados, acessados,
usados, protegidos e implementados.

Programas podem ler e criar novas estruturas chamadas arquivos


conforme desejarem, apenas se preocupando com o conteúdo do
arquivo, sem atentar para onde ou como ele está sendo armazenado.
Por esse motivo, é importante que todo arquivo possua um nome, isso é
essencial para que possamos identificá-lo. O nome de um arquivo pode
ser separado em duas partes, a primeira sendo seu nome propriamente
dito e a segunda, a qual chamamos de extensão de arquivo, dá algumas
dicas a respeito de como é o arquivo. Essas duas partes são separadas por
um ponto. Por exemplo, o arquivo “programa.c” possui como extensão

www.esab.edu.br 117
de arquivo “c”, que indica que o arquivo é um arquivo de texto contendo
código fonte escrito na linguagem C. Extensões de arquivo podem
mudar entre diferentes SOs.

Nos sistemas de arquivo do sistema Windows, por exemplo, poderia


existir também um arquivo “programa.exe”. Nesse caso, ele seria um
arquivo executável, ou seja, o arquivo possui o código e dados do
programa e, quando aberto, ativa a sua execução. Extensões são úteis
para programas que conseguem ler diferentes formatos de arquivo, já
que dessa forma esses programas podem de antemão saber como é o
conteúdo do arquivo.

Veremos agora uma figura que mostra em mais detalhes como é a


estrutura interna de um arquivo executável, sem nos preocupar muito
com detalhes muito específicos de um ou outro sistema de arquivos.

Número mágico
Tamanho do texto
Tamanho dos dados
Cabeçalho

Tamanho dos dados não inicializados


Tamanho da tabela de símbolos
Ponto de entrada

Flags

Texto

Dados

Bits de realocação

Tabela de símbolos

Figura 27 – Modelo de como um arquivo executável pode ser estruturado.


Fonte: Tanenbaum (2010, p. 162).

A Figura 27 mostra como um arquivo executável pode ser estruturado.


Todo arquivo possui um cabeçalho que contém diversas informações
sobre o arquivo. No caso de um arquivo executável, esse cabeçalho deve

www.esab.edu.br 118
ter um número mágico, responsável por dizer ao SO que esse arquivo é
executável. É importante que o SO consiga facilmente diferenciar um
arquivo executável de um não executável, pois o tratamento que eles
recebem quando o usuário os abre é totalmente diferente. Se um arquivo
não executável for aberto, o SO precisa encontrar um programa que
consiga ler e interpretar o conteúdo do arquivo. Por exemplo, se o arquivo
for um vídeo, o SO pode verificar se existe instalado no computador
algum programa que reproduz vídeos. Por outro lado, se o arquivo aberto
for um executável, o SO deve pegar o conteúdo do arquivo, criar um
processo e solicitar ao processador que execute o programa.

Além desse número mágico, o cabeçalho também informa o tamanho


do código do programa, o tamanho do trecho de dados, do trecho de
dados não inicializados e da tabela de símbolos. Por fim, o cabeçalho
ainda guarda o endereço da primeira instrução do programa, entre outras
informações que dependem do SO.

Uma dessas informações úteis são as permissões do arquivo. A


implementação de permissões de arquivos varia bastante entre diferentes
SOs, porém praticamente todos possuem alguma forma de bloquear o acesso
ao arquivo a só um ou a alguns usuários. Arquivos geralmente possuem
permissões para leitura, escrita e também execução, caso sejam executáveis.

A seguir veremos outro conceito importante, o de diretório, e qual é a


sua função no sistema de arquivos.

19.2 Diretórios
Em um sistema com milhares ou milhões de arquivos, é preciso existir
uma forma de organizá-los para facilitar seu uso por parte do usuário. A
maioria dos SOs possuem uma interface gráfica que permite ao usuário
explorar o conteúdo da memória secundária e visualizar todos os arquivos
no computador, permitindo que o usuário execute programas ou abra
seus arquivos. Sem uma boa organização, essa interface gráfica mostraria
uma simples lista com todos os milhares ou milhões de arquivos.

www.esab.edu.br 119
Para resolver esse problema, a maioria dos SOs implementa o conceito
de diretório, que nada mais é do que uma espécie de pasta onde é
possível colocar arquivos ou outros diretórios. Ter diretórios e arquivos
dentro de outros diretórios gera uma estrutura de árvore que permite
uma organização hierárquica e bem mais simplificada dos arquivos
do computador. O sistema Windows possui uma organização assim,
que pode ser conferida através do explorador de arquivos do sistema.
A Figura 6, mostrada na unidade 6, apresenta exatamente como seria
essa hierarquia de arquivos no sistema Windows. Arquivos e diretórios
formam a visão de um sistema de arquivos do ponto de vista dos
usuários. A seguir, veremos o ponto de vista dos projetistas de um sistema
de arquivos.

19.3 Sistemas de arquivos


De acordo com Tanenbaum (2010), os implementadores de sistemas de
arquivos preocupam-se com a forma com que arquivos e diretórios são
armazenados, como o espaço em disco é gerenciado e como fazer tudo
funcionar de forma confiável e eficiente.

Geralmente a memória secundária é dividida em blocos de dados. O


tamanho dado a cada bloco varia dependendo do sistema de arquivos.
Existem várias formas de armazenar os arquivos dentro dos blocos da
memória secundária. A forma mais simples se chama alocação contígua,
na qual, de acordo com Tanenbaum (2010), cada arquivo é armazenado
em blocos consecutivos.

Por exemplo, se cada bloco for de 1 KB, um arquivo de 50 KB seria


armazenado em 50 blocos consecutivos da memória. Se o arquivo tiver
menos de 1 KB, ainda assim ele ocupará um bloco inteiro, pois um
único bloco só pode ser ocupado por um arquivo. Nesse caso, o espaço
restante no bloco não seria utilizado. A figura a seguir mostra um
cenário semelhante. No caso do programa à direita, 300 bytes do bloco
estão sendo desperdiçados, pois não são usados pelo programa que está
ocupando o bloco em questão e não podem ser utilizados por nenhum
outro bloco.

www.esab.edu.br 120
Um programa de 700 bytes
ocupando um bloco de 1 KB,
Um programa de 2 KB deixando 300 bytes sem serem
ocupando dois blocos de 1 KB. usados por nenhum programa.

1 KB 700 bytes

1 KB

Figura 28 – Dois cenários possíveis de utilização dos sistemas de arquivos.


Fonte: Elaborada pelo autor (2014).

Embora simples, a alocação contígua não é muito eficiente. Sistemas


modernos costumam possuir estruturas que controlam a alocação e
permitem uma alocação mais dinâmica, usando tabelas para controlar
onde estão alocados os bytes de cada arquivo.

Terminamos assim esta unidade a respeito do gerenciamento de


arquivos. Vimos o que são arquivos, o que são diretórios e como eles
são importantes para o gerenciamento do sistema de arquivos, pois é
através deles que o SO organiza todos os dados na memória secundária.
Na próxima unidade, estudaremos alguns detalhes a respeito desse
gerenciamento e então veremos exemplos reais da implementação de
sistemas de arquivos.

www.esab.edu.br 121
Gerenciamento de arquivos e
20 diretórios
Objetivo
Descrever o gerenciamento de arquivos e diretórios com exemplos de
sistemas de arquivos reais.

Na unidade anterior, iniciamos nosso estudo a respeito do gerenciamento


de arquivos realizado pelo SO. Vimos que o componente do SO
responsável por esse gerenciamento é o sistema de arquivos e que ele
gerencia o espaço usado abstraindo os dados armazenados na forma de
arquivos e diretórios.

Vimos também que, internamente, o sistema de arquivos armazena o


conteúdo de cada arquivo em blocos da memória secundária, embora a
forma como esses blocos são usados possa variar conforme a implementação.

Nesta unidade, continuaremos vendo detalhes a respeito do


gerenciamento de arquivos e também veremos casos reais de sistemas de
arquivos. Fundamentaremos nossos estudos desta unidade no trabalho de
Tanenbaum (2010). Para iniciar, vamos ver mais sobre o gerenciamento
de arquivos.

20.1 Gerenciamento de arquivos


Como vimos na unidade anterior, a memória secundária é geralmente
dividida em blocos. Quando um arquivo é criado, ele também é dividido
em blocos para poder ocupar a memória. Esses blocos são colocados
na memória não necessariamente em ordem, mas dependendo da
forma como o sistema de arquivos foi implementado. A quantidade de
blocos na memória, porém, é limitada. É preciso realizar, então, um
gerenciamento do espaço usado pela memória secundária.

www.esab.edu.br 122
Na implementação de um sistema de arquivos com alocação em blocos,
o primeiro ponto que deve ser respondido é qual tamanho de bloco
usar, da mesma forma como o tamanho da página era importante na
paginação da memória principal, como estudamos anteriormente. A
escolha do tamanho do bloco pode depender de aspectos físicos da mídia
que é usada como memória secundária. No caso de um disco rígido, um
bloco pode ser do tamanho de um setor do disco ou de uma trilha ou de
um cilindro. De acordo com Tanenbaum (2010), se o tamanho do bloco
for do tamanho de um cilindro, isso significa que até mesmo arquivos de
1 byte ocupariam um cilindro inteiro, o que é inviável.

Por outro lado, diminuir o tamanho dos blocos faz com que cada
arquivo possa precisar de mais blocos para ser armazenado, diminuindo
o desempenho de leituras e escritas na memória. No fim das contas, a
decisão do tamanho do bloco de um lado prejudica o uso do espaço e de
outro prejudica aspectos de tempo de execução. Ainda de acordo com
Tanenbaum (2010), um tamanho de bloco de 4 KB parece bastante
apropriado para a maioria dos casos.

Outro ponto importante na implementação de gerenciamento de


arquivos é a forma como o SO gerencia os blocos livres. Uma das
principais formas é manter uma lista encadeada de blocos, em que cada
um possui informações sobre tantos blocos livres quanto ele conseguir
armazenar. Outra forma seria usar um mapa de bits que indica quais
blocos estão livres e quais não estão.

Essas características vistas previamente e as estudadas na unidade anterior


são compartilhadas por todos os sistemas de arquivos. A seguir vamos ver
algumas especificidades do sistema de arquivos do sistema MS-DOS.

20.2 O sistema de arquivos do MS-DOS


De acordo com Tanenbaum (2010), o sistema de arquivos do MS-DOS,
chamado FAT, foi o primeiro a ser usado nos primeiros computadores da
IBM sendo, por muitos anos, o principal sistema de arquivos do sistema
Windows, embora não o seja mais atualmente. Mesmo assim, ele ainda
é um dos sistemas de arquivos mais usados do mundo, pois também é
utilizado em diversos outros sistemas, principalmente dispositivos móveis
como câmeras, tocadores de MP3 e celulares.
www.esab.edu.br 123
Ainda de acordo com Tanenbaum (2010), para ler um arquivo, um
programa no sistema MS-DOS precisa primeiro usar uma chamada de
sistema chamada open, que entrega ao programa um descritor do arquivo
que possui algumas informações sobre ele e fornece também os meios
para que o arquivo seja de fato lido ou escrito.

No MS-DOS, toda entrada de diretório possui 32 bytes que descrevem


seu conteúdo e dão características a respeito do arquivo, por exemplo,
seu nome, tamanho e data de criação. Nesses 32 bytes, ficamos sabendo
se o arquivo é somente de leitura ou não. O problema é que, desses 32
bytes, para cada entrada de arquivo há apenas sete bits para representar o
ano em que o arquivo foi criado ou a última vez em que foi modificado.
Esse ano é contado a partir de 1980, então o menor ano possível é 1980
e o maior é 2107, já que o maior número binário representável em sete
bits é 127. Por esse motivo, sem que os projetistas do sistema de arquivos
façam algo, no ano de 2108 os arquivos do MS-DOS começarão a
apresentar datas de criação ou modificação inválidas.

O MS-DOS controla o conteúdo dos arquivos usando uma tabela de


alocação na memória principal, que informa quais são os blocos de cada
arquivo. A entrada de diretório contém o número do primeiro bloco do
arquivo.

As primeiras versões do FAT possuíam endereços curtos para armazenar


o tamanho dos arquivos e alguns outros dados, fazendo com que o
sistema só pudesse ter arquivos de até 2 GB de tamanho, o que logo se
tornou inviável e foi consertado para o sistema Windows 95. Problemas
como esse foram o foco do lançamento de novas versões do FAT, como o
FAT-32. A seguir, vamos conhecer algumas especificidades do sistema de
arquivos do Unix.

www.esab.edu.br 124
20.3 O sistema de arquivos do Unix
De acordo com Tanenbaum (2010), o sistema de arquivos do Unix,
chamado V7, sempre foi bastante sofisticado, já que o sistema é derivado
do Multics. O V7 existe na forma de uma árvore, com um diretório-raiz
que é como o pai de todos os outros diretórios.

Ao contrário do sistema de arquivos do MS-DOS, cada entrada de


diretório do sistema de arquivos do Unix possui uma entrada para cada
arquivo do diretório, e cada entrada dessas contém apenas o número de
um i-node, que é uma estrutura especial que contém o endereço de cada
bloco do arquivo. Com essa organização, o Unix consegue gerenciar os
arquivos no sistema de forma bastante eficiente.

Ainda segundo Tanenbaum (2010), cada i-node, além de informar onde


está cada bloco do arquivo, também possui outras informações, como
o tamanho do arquivo, sua data de criação, a data do último acesso, a
data da última modificação, quem é o proprietário do arquivo, grupo,
informações de proteção e um contador de entradas de diretório que
apontam para o arquivo. O Unix sabe quando um arquivo foi excluído e
não está mais visível quando esse contador chega a zero.

Para arquivos muito grandes, o i-node do arquivo contém o endereço


de alguns blocos e o endereço do que chamamos de bloco indireto
simples, que consiste em uma estrutura que armazena diversos outros
endereços de blocos do mesmo arquivo. Se o arquivo for ainda maior, esse
bloco indireto simples pode conter ainda o endereço de outros blocos,
chamados blocos indiretos duplos. Um possível bloco indireto triplo
ainda existe caso os blocos indiretos duplos não sejam suficientes. Quando
o arquivo é aberto, o sistema percorre o i-node, e todos os possíveis blocos
indiretos para saber onde estão todos os blocos do arquivo.

www.esab.edu.br 125
A Figura 29 mostra como é um i-node do Unix com essas estruturas de
blocos indiretos.

I - node
Atributos Bloco
indireto
Endereços de disco

simples

Bloco Endereços de
indireto blocos de dado
duplo

Bloco
indireto
triplo

Figura 29 – Um i-node do Unix.


Fonte: Tanenbaum (2010, p. 199).

Dessa forma, terminamos nossos estudos a respeito do gerenciamento


de arquivos de um computador, o que é realizado pelo sistema de
arquivos do SO. Na próxima unidade mudaremos de tópico novamente,
começando a estudar o gerenciamento da entrada e saída de dados em
um computador. Continue atento!

Tarefa dissertativa
Caro estudante, convidamos você a acessar o
Ambiente Virtual de Aprendizagem e realizar a
tarefa dissertativa.

www.esab.edu.br 126
Gerenciamento de entrada/saída
21 de dados
Objetivo
Contextualizar a entrada e saída de dados (E/S) e o seu
gerenciamento.

Nas unidades anteriores estudamos sobre o gerenciamento de arquivos,


realizado pelo sistema de arquivos, que é parte de todo SO. Vimos o que
são arquivos, o que são diretórios e como funciona um sistema de arquivos.
Nesta e na próxima unidade, estudaremos o gerenciamento de entrada e
saída de dados em um computador, que também é função do SO.

Como estudamos na unidade 6, os programas se comunicam de diversas


formas com diferentes dispositivos de entrada e saída. Por exemplo, um
programa pode receber comandos de dispositivos, como teclado e mouse,
e também pode enviar dados para serem mostrados em uma tela ou
impressos por uma impressora. Programas também podem se comunicar
com dispositivos de rede, mandando ou recebendo dados da internet, por
exemplo. Por fim, programas também podem se comunicar com discos
ou com o próprio sistema de arquivos, lendo ou criando novos arquivos,
e isso também é uma forma de entrada e saída de dados.

Cada dispositivo de entrada e saída pode ter características muito


específicas e diferentes modos de execução, mas é função do SO abstrair
essas diferenças e permitir que os programas se comuniquem com esses
dispositivos da maneira mais próxima possível. Por exemplo, discos,
CDs, DVDs, pen drives, todos esses dispositivos de armazenamento
funcionam de forma bem diferente, porém o SO abstrai seu
funcionamento de forma que, para um programa, tanto faz se o arquivo
que ele está lendo está em um CD ou pen drive.

Para entender o gerenciamento de entrada e saída realizado pelo SO,


precisamos primeiro compreender alguns princípios de hardware desses

www.esab.edu.br 127
dispositivos e depois precisamos entender alguns princípios de software.
Isso é o que estudaremos nesta unidade, apoiando-nos no trabalho de
Tanenbaum (2010). Iniciaremos pelos princípios de hardware.

21.1 Princípios de hardware de E/S


De acordo com Tanenbaum (2010), os dispositivos de entrada e saída
(E/S) consistem em uma parte mecânica e uma eletrônica. A parte
mecânica é o dispositivo em si. No caso de uma impressora, consiste em
todo o mecanismo responsável por realizar impressões. Já no teclado,
consiste nas teclas e no cabo responsável por transmitir a informação até
o computador.

A parte eletrônica do dispositivo conecta a parte mecânica ao


computador e é chamada de controlador do dispositivo. Essa parte
eletrônica normalmente é formada por um circuito eletrônico que é
conectado ao computador, geralmente à placa-mãe. O controlador é o
primeiro estágio na comunicação entre o dispositivo e o computador, e
ele próprio já possui várias funções que simplificam o uso do dispositivo.
Por exemplo, uma das funções desse controlador é realizar uma
espécie de controle de erros. Se o controlador detecta algum erro na
comunicação entre dispositivo e computador, ele pode tentar corrigi-lo,
geralmente solicitando que a comunicação seja refeita.

Outra função do controlador é pegar bits soltos que o dispositivo envia


e organizá-los de forma que o SO tenha mais facilidade para interpretá-
los. Há dispositivos que possuem um funcionamento mais complexo,
como monitores, que precisam desenhar na tela o que a interface gráfica
do SO deseja. Como afirma Tanenbaum (2010), sem a existência desse
controlador, o SO teria que se preocupar em passar para o monitor
exatamente como desenhar a interface, bit a bit. Graças ao controlador
do monitor, esse trabalho é bastante simplificado.

Quando um programa se comunica com um dispositivo de E/S ou


quando um dispositivo deseja solicitar algo ao SO, é necessário que haja
troca de informações entre eles, ou seja, o processador precisa executar
instruções que acessem dados do dispositivo. Para isso, é preciso que o
dispositivo possua alguma forma de disponibilizar seus dados para acesso
por causa do processador.
www.esab.edu.br 128
Todo dispositivo de E/S possui registradores, que podem ser acessados
pelo SO ou, mais especificamente, pelo processador, para que este último
se comunique com o dispositivo. A forma como esses registradores são
acessados pode variar. Existem algumas formas de implementar essa
comunicação, sendo que a mais comum delas se chama E/S mapeada
em memória. Dizer que a E/S está mapeada em memória significa dizer
que os dados do dispositivo ficam na memória principal, como se fossem
parte dela. Em outras palavras, os dados dos registradores do dispositivo
ficam na memória principal, em que o processador consegue acessar com
facilidade e o SO consegue gerenciar também com facilidade.

Na próxima unidade, estudaremos essa comunicação detalhadamente;


agora vamos introduzir alguns dos conceitos presentes no gerenciamento de
dispositivos de E/S. Para ler dados do dispositivo, o processador pode lê-los
byte a byte, os quais estão mapeados na memória principal. Primeiramente,
os dados são lidos pelo controlador do dispositivo, que transfere os dados
para seus buffers internos. Então o processador copia os dados byte a
byte para a memória principal, onde eles são novamente lidos para serem
utilizados por algum programa. No entanto, esse mecanismo acaba
gastando muito tempo fazendo a leitura de dados do dispositivo.

Ainda de acordo com Tanenbaum (2010), a solução para esse problema


está na utilização do Acesso Direto à Memória, ou DMA, da sigla em
inglês Direct Memory Access. O uso de DMA depende da presença
de um controlador de DMA no computador, além disso, o SO precisa
suportar seu uso. Com o uso de DMA, o processador configura o
controlador de DMA para realizar a leitura de dados, e o controlador
de DMA copia os dados do dispositivo diretamente para a memória,
avisando o SO quando terminar. Nesse momento, o processador já acessa
os dados diretamente na memória principal, sem se preocupar com a
cópia dos dados, que já foi realizada pelo controlador de DMA. A seguir
vamos conhecer alguns princípios de software de E/S.

www.esab.edu.br 129
21.2 Princípios de software de E/S
Agora, iremos conhecer alguns princípios de software que são
importantes quando trabalhamos com E/S em programas. Vimos
anteriormente que programas de computador devem ser capazes de se
comunicar com diferentes dispositivos de E/S sem que mudanças sejam
realizadas no código do programa. Por exemplo, um programa deveria ser
capaz de ler um arquivo e interpretar seus dados independentemente do
arquivo estar em um disco, CD, DVD ou em um pen drive. Tanenbaum
(2010) chama esse conceito de independência do dispositivo.

Semelhante a esse conceito, existe o que Tanenbaum (2010) chama de


nomeação uniforme. De acordo com o autor, programas deveriam acessar
dispositivos de E/S através de seus nomes e esses nomes deveriam seguir
as mesmas regras de criação. No Unix, por exemplo, todo dispositivo
de armazenamento não volátil conectado ao computador é tratado
como parte do sistema de arquivo e pode ser acessado como se fosse um
arquivo qualquer.

O tratamento de erros também é um tópico que deve ser levado em


consideração na criação de software que realize E/S ou controle de
dispositivos de E/S. Esses programas dependem da comunicação de
dados e há diversas vulnerabilidades que podem afetar a troca de dados,
muitas delas inerentes ao próprio dispositivo ou ao barramento pelo qual
trafegam seus dados.

De acordo com Tanenbaum (2010), os erros devem ser tratados o mais


próximo possível do hardware, por exemplo, pelo próprio controlador do
dispositivo, como já vimos anteriormente nesta unidade. Quanto mais
próxima do hardware for feita a recuperação do erro, mais rápida será
essa recuperação, que muitas vezes consiste em simplesmente realizar a
comunicação dos dados novamente.

Por fim, projetistas devem se preocupar com a forma com que a


transferência dos dados é realizada. Um programa que se comunique
com um dispositivo de E/S pode ler e escrever dados no dispositivo
de forma síncrona, também chamada de bloqueante, ou de forma

www.esab.edu.br 130
assíncrona, através de interrupções. Esse será um dos nossos tópicos de
estudo da próxima unidade, na qual continuaremos estudando a respeito
do gerenciamento de E/S de um computador.

Terminamos aqui esta unidade introdutória do gerenciamento de E/S,


na qual pudemos conhecer os princípios de hardware e software que
determinam como deve funcionar a E/S em um sistema computacional.

Estudo complementar
Nesta unidade você estudou os princípios de
hardware e software de dispositivos de E/S
de dados. Para complementar seus estudos
e conhecer um pouco mais a respeito desses
dispositivos, faça uma leitura do material
disponível clicando aqui.

www.esab.edu.br 131
Modos de operação de entrada/
22 saída de dados
Objetivo
Apresentar técnicas de transferência de dados, como polling e
interrupções.

Na unidade anterior, começamos a estudar o gerenciamento da entrada e


saída de dados realizadas pelo SO. Vimos que dispositivos de E/S podem
ser bem diferentes entre si e que praticamente todos eles têm uma parte
mecânica e uma parte eletrônica, esta última responsável por conectar o
dispositivo ao computador. No outro oposto, temos softwares que fazem
uso desses dispositivos de E/S conectados ao computador. Esses softwares
desejam se comunicar com a maior quantidade possível de dispositivos
sem que mudanças no código sejam necessárias, ou seja, eles querem que
as diferentes características de cada dispositivo sejam abstraídas para que
consigam usar os dispositivos sem se preocupar com elas.

Vimos também que quando trabalhamos com E/S devemos nos


preocupar com o tratamento de erros, pois a comunicação entre
dispositivos está sempre sujeita a falhas de transmissão.

Nesta unidade, continuaremos estudando a respeito dos dispositivos


de E/S, conhecendo mais sobre os softwares que fazem uso desses
dispositivos e conhecendo algumas técnicas de transferência de dados
entre programas e dispositivos. Basearemos novamente nossos estudos no
trabalho de Tanenbaum (2010).

Na unidade anterior, vimos que um dispositivo de E/S possui uma parte


mecânica e uma parte eletrônica que se conecta ao computador. Vimos
também que cada dispositivo possui registradores, nos quais ele escreve
dados e lê comandos, e vimos que o SO fornece uma forma de os programas
se comunicarem com cada dispositivo através desses registradores. É preciso,
porém, que haja mais um componente intermediando essa comunicação,
pois cada dispositivo possui uma quantidade diferente de registradores e
funções diferentes para cada registrador.

www.esab.edu.br 132
De acordo com Tanenbaum (2010), para que o SO consiga compreender
cada dispositivo, o SO precisa de um componente de software que
entenda os registradores de cada dispositivo. Esse componente é
chamado de driver do dispositivo. É através desse driver que o SO se
comunica com o dispositivo. Como os registradores de cada dispositivo
são diferentes, é preciso um driver para cada tipo diferente de dispositivo.

Dessa forma, o dispositivo possui um controlador eletrônico que o


conecta ao computador, e o SO possui um driver de dispositivo que se
comunica com esse controlador para ler e escrever nos seus registradores.
Por fim, os programas de usuário podem se comunicar com o SO para
acessar o driver do dispositivo. A seguir, a Figura 30 mostra esse cenário.

Processo do usuário

Espaço Programa
do usuário do usuário

Restante do sistema operacional


Espaço
do núcleo
Driver da Driver da Driver do
impressora câmera de vídeo CD-ROM

Controlador Controlador de Controlador


de impressora câmera de vídeo de CD-ROM

Figura 30 – Posicionamento dos dispositivos de E/S, seus controladores,


seus drivers, sua relação com o SO e os programas de usuário.
Fonte: Tanenbaum (2010, p. 216).

Note que os drivers de cada dispositivo fazem parte do SO e executam


no espaço do núcleo. Como vimos na unidade 4, esse é o cenário
mais comum, pois é o cenário dos SOs monolíticos e de alguns
híbridos também. A seguir, vamos estudar em mais detalhes como é a
comunicação dos programas de usuário com os drivers de dispositivos.
www.esab.edu.br 133
22.1 Operações de E/S
De acordo com Tanenbaum (2010), existem três maneiras de se trabalhar
com dispositivos de E/S. A primeira delas, que estudaremos agora,
se chama E/S programada. Nesse cenário, todo o trabalho de E/S é
realizado pelo próprio processador. Quando um programa deseja enviar
um conjunto de bytes para um dispositivo de E/S, ele o faz através do SO,
usando uma chamada de sistema. O SO, então, pega o conjunto de bytes
que deve ser enviado ao dispositivo e o copia para um buffer interno.

Logo, o SO, através do driver do dispositivo, escreve cada byte do


buffer nos registradores do dispositivo, um de cada vez. Os dispositivos
geralmente demoram um pouco para ler cada byte e o SO realiza
o que chamamos de polling, ou espera ocupada, do inglês busy
waiting. Esse polling realizado pelo SO consiste em ficar verificando,
ininterruptamente, se o dispositivo já leu o byte. Quando o dispositivo
já tiver lido o byte, o SO escreve o próximo byte e assim por diante, até
que todos os bytes estejam escritos. Então, finalmente, o SO retorna a
execução para o programa do usuário.

Esse cenário é o mais simples e é o mais adequado para alguns tipos de


sistemas, porém possui uma grande desvantagem, pois ele mantém o
processador em uso durante todo o tempo de transmissão dos dados.
Isso ocorre por causa da operação de polling, que força o processador a
verificar o estado do dispositivo de forma ininterrupta até que cada byte
tenha sido lido. Esse tempo que o processador fica verificando o estado
do dispositivo é um tempo perdido, o qual o processador poderia estar
usando para executar instruções de outros programas.

A segunda forma de se trabalhar com E/S na programação é usando


interrupção. Essa interrupção é aquela interrupção de hardware, que
estudamos brevemente na unidade 12 e consiste em um sinal enviado pelo
dispositivo de E/S para o SO, informando que ele requer alguma atenção
por parte do SO. Um dispositivo de E/S pode emitir uma interrupção
quando dados chegam pela rede ou quando ele termina de realizar algum
trabalho, por exemplo. Quando uma interrupção ocorre, o escalonador
interrompe a execução da thread que estava executando e permite ao SO
verificar a razão da interrupção proveniente do dispositivo.

www.esab.edu.br 134
Vamos ver como seria, então, a transmissão dos dados do exemplo prévio
se o mecanismo de transmissão usasse interrupções. Nesse cenário,
o programa novamente usa uma chamada de sistema e o SO copia
os bytes a serem enviados para um buffer interno. Em seguida, o SO
escreve em um registrador do dispositivo o primeiro byte do buffer.
Nesse momento, ao invés de entrar em uma espera ocupada, o processo
é interrompido e o escalonador permite a execução de outro processo,
otimizando o uso do processador.

Quando o dispositivo tiver lido com sucesso aquele byte, ele emite
uma interrupção para avisar ao SO. Nesse momento, o escalonador
interrompe novamente o código que está executando e permite que o
SO escreva no registrador do dispositivo o próximo byte do buffer. Os
bytes seguintes são escritos no dispositivo seguindo o mesmo mecanismo,
até que a transmissão termine e o controle da execução volte para o
programa do usuário.

A vantagem desse mecanismo que usa interrupções é que o processador


pode realizar outras tarefas enquanto a transmissão é realizada. Uma
desvantagem é que ocorre uma nova interrupção para cada byte escrito
no dispositivo. Como vimos quando estudamos escalonamento, uma
interrupção significa uma troca inteira de contexto, o que pode levar
algum tempo, dependendo do sistema. Se muitos bytes forem escritos, a
quantidade excessiva de trocas de contexto pode prejudicar o desempenho
do sistema. A terceira forma de se realizar E/S em programas, que será
estudada a seguir, tenta propor uma solução a esse problema.

22.2 Acesso direto à memória (DMA)


De acordo com Tanenbaum (2010), uma solução para o problema do
uso do processador na transmissão de dados está no uso de DMA. Como
vimos na unidade anterior, o uso de DMA permite que dispositivos de
E/S acessem diretamente a memória principal. Esse acesso é realizado
através do controlador de DMA, que é um componente de hardware
independente do processador e que realiza seu próprio processamento.

www.esab.edu.br 135
Nesse cenário, o programa de usuário novamente solicita o envio de
dados ao SO, que novamente copia os dados para seu buffer interno.
Nesse momento o processador configura o controlador de DMA para
realizar a transmissão e delega a função de realizar a transmissão para o
controlador de DMA. Toda a transmissão dos dados do buffer interno
do SO para os registradores do dispositivo é realizada pelo controlador
de DMA, e o processador do computador pode, então, se preocupar
com outros processos, sem ter que esperar a transmissão acabar ou
interrupções ocorrerem.

O controlador de DMA, por sua vez, realiza E/S programada, como


vimos anteriormente, através do mecanismo de polling, porém isso não
é um problema já que a transmissão de dados é sua função. A grande
vantagem do uso de DMA está na grande redução de interrupções para
transmissões entre programas e dispositivos de E/S. A única desvantagem
é que o controlador de DMA costuma ser bem mais lento que o
processador. Nesse caso, se o processador estiver ocioso durante uma
transmissão, o uso de DMA pode prejudicar o desempenho. Porem, em
geral, utilizá-lo é bastante vantajoso.

Terminamos aqui nossos estudos a respeito do gerenciamento de E/S


realizado pelo SO. Vimos os princípios de hardware e software desses
dispositivos, os diferentes modos de transmissão que o SO pode usar
e que os drivers de dispositivos são componentes de software do SO
responsáveis por realizar a comunicação entre os programas de usuário
e os controladores dos dispositivos. Na próxima unidade, estudaremos
tópicos importantes de sistemas operacionais, como a segurança e a
confiabilidade desses sistemas.

www.esab.edu.br 136
Segurança e confiabilidade em
23 sistemas operacionais
Objetivo
Apresentar conceitos referentes à segurança e confiabilidade em
sistemas operacionais.

Ao longo da disciplina estudamos todos os componentes de um sistema


operacional. Vimos o gerenciamento de processos, escalonamento,
gerenciamento de memória, gerenciamento de arquivos realizado pelo
sistema de arquivos e também o gerenciamento de dispositivos de E/S
realizado pelos drivers de dispositivos. Esses componentes, somados ao
conjunto de programas que auxiliam seu funcionamento, consistem na
visão geral de um sistema operacional como o que está presente em todos
os computadores.

Nesta unidade, vamos dar um pouco de atenção a alguns tópicos


extras que não fazem parte da base de um sistema operacional, porém
precisam ser levados em consideração no projeto de um SO, pois são
importantes para que ele realize com sucesso sua tarefa de gerenciar os
recursos do computador.

Nesta unidade, vamos estudar aspectos de segurança e confiabilidade


de um SO, utilizando como base o trabalho de Tanenbaum (2010). O
nosso objetivo aqui é compreender por que a questão da segurança é
importante para um SO. Para tanto, estudaremos as possíveis ameaças à
integridade de um sistema e os possíveis invasores com os quais os SOs
precisam lidar. Por fim, veremos um pouco sobre as possíveis perdas
acidentais de dados, que também são um risco para o sistema. Para
iniciar, vamos entender melhor as preocupações com segurança presentes
no projeto de um SO.

www.esab.edu.br 137
23.1 Preocupações com segurança
Com o passar dos anos, cada vez mais pessoas usam computadores e
passam cada vez mais tempo na frente deles. Hoje em dia, a maioria
das pessoas possui informações valiosas ou confidenciais que elas não
gostariam que ficassem livres ao acesso de qualquer pessoa. Como boa
parte da vida das pessoas agora está nos computadores, é natural que se
queira manter a privacidade das diversas informações contidas neles.

Esse cenário se estende também para empresas, universidades e órgãos


do governo. Empresas podem manter nos computadores informações
valiosas sobre movimentos estratégicos, enquanto governos podem
guardar em computadores informações sobre forças militares e estratégias
de defesa nacional.

A segurança dos dados que estão em um computador é, então, uma


questão de suma importância, pois muitas vezes manter uma informação
fora do alcance de pessoas não autorizadas é tão importante quanto
armazenar e guardar a informação corretamente. Ou seja, os mecanismos
que um SO utiliza para manter a segurança dos dados podem ser tão
importantes quanto o bom funcionamento do sistema de arquivos ou do
gerenciamento de memória.

De acordo com Tanenbaum (2010), existe um fenômeno que vem


ocorrendo nas últimas décadas e que tem prejudicado os esforços para
manter a segurança dos dados em um computador. Esse fenômeno é
o da crescente quantidade de erros de código nos SOs, e a crescente
tolerância dos usuários quanto à existência desses erros. Os SOs se
desenvolveram muito rapidamente nas últimas décadas para suprir as
necessidades dos usuários, e esse crescimento acelerado de componentes
de software tão complexos fez com que esses SOs tivessem uma grande
quantidade de erros no código, os chamados bugs. Ao mesmo tempo em
que a quantidade de bugs crescia, os usuários também passaram a ficar
mais tolerantes a esses bugs, muitas vezes, vendo-os como fenômenos
naturais quando na verdade eles não passam de falhas no processo de
desenvolvimento do SO.

www.esab.edu.br 138
O problema é que esses bugs são a principal fonte de problemas de
segurança em SOs. Os componentes do SO deveriam funcionar sem
erros, cumprindo seus objetivos como foram projetados. Um erro em um
componente do SO faz com que ele se comporte de forma indevida. Esse
comportamento estranho pode ser explorado por pessoas maliciosas para
fazer com que o SO realize tarefas que não deveria.

Existem, assim, diversas ameaças e invasores possíveis que colocam em risco


a integridade de um SO. Veja mais sobre esse assunto no tópico a seguir.

23.2 Ameaças e invasores


Segundo Tanenbaum (2010), um dos objetivos de um SO
quanto à segurança é manter a confidencialidade dos dados no
computador, conforme a vontade do proprietário dos dados. Manter
a confidencialidade significa manter em segredo os dados que são
secretos. Em outras palavras, se o proprietário de um arquivo definir
que apenas ele pode ler determinado arquivo, então o SO deve garantir
que em nenhum momento algum outro usuário do computador leia
aquele arquivo. Para isso, o SO deve fornecer um mecanismo que
permita a qualquer usuário definir quem pode acessar seus dados,
seja apenas o próprio proprietário ou apenas um pequeno grupo de
usuários do computador etc. A exposição de dados é a maior ameaça à
confidencialidade dos dados em um computador.

Ainda de acordo com Tanenbaum (2010), outro objetivo do SO em


relação à segurança é manter a integridade dos dados, o que significa
permitir a alteração dos dados apenas por usuários autorizados. Em
outras palavras, após os arquivos serem criados, eles devem permanecer
com os mesmos dados, a não ser que o proprietário do arquivo ou
alguém em quem ele confie realize alguma alteração.

Outro objetivo de um SO é garantir a disponibilidade do sistema, ou


seja, o sistema deve estar sempre disponível para ser acessado e usado
pelos usuários. Esse objetivo não se refere apenas ao SO executar suas
funções sem erro. Uma perigosa ameaça aos computadores são os
famosos ataques de negação de serviço. Esses ataques consistem em se

www.esab.edu.br 139
executar em um computador um programa, um grupo de programas ou
até mesmo um conjunto de funções do SO que utilize excessivamente os
recursos do processador, fazendo com que o computador fique lento ou
pare de funcionar e com que os serviços realizados pelo computador se
tornem indisponíveis.

Esse tipo de ataque é muito comum aos servidores de páginas da


internet. Uma forma de tirar um site do ar é bombardear o servidor do
site com inúmeras requisições enviadas pela internet, fazendo com que
o servidor não consiga mais fornecer as páginas do site, o que pode fazer
com que diversos usuários fiquem sem conseguir acessá-lo.

Além da segurança em relação aos dados do computador, outro


aspecto importante é a segurança do próprio computador. Há pessoas
maliciosas que não desejam apenas acessar ou manipular os arquivos no
computador, elas desejam também tomar o controle dele, fazendo com
que o computador da vítima execute programas definidos pelo invasor ou
que realize ações que não deveria. Ao controlar o computador de outra
pessoa, o invasor pode realizar atividades ilegais e não ser identificado.

Há diversos tipos diferentes de invasores, que são aqueles usuários


que tentam de alguma forma burlar os objetivos do SO descritos
anteriormente. Consideramos um invasor todo usuário que tente acessar
ou manipular arquivos que ele não tem autorização para manipular ou
que tente prejudicar a disponibilidade do sistema ou, ainda, aquele que
de alguma forma tente tomar o controle do computador de outra pessoa
sem que ela autorize.

Para Tanenbaum (2010), do ponto de vista de segurança, há diversos


níveis de invasores, compreendendo desde usuários leigos até a espionagem
comercial ou militar. Quanto maior o invasor, mais complexo terá que ser
o mecanismo do SO para manter a segurança das informações.

Por fim, os vírus podem ser considerados também como invasores de


um computador, como comentamos na unidade 5. Eles são semelhantes
aos programas executados por pessoas que invadem e tomam o controle
do computador de outras pessoas. Porém, vírus são mais independentes,
pois podem se proliferar pela internet, invadindo milhares ou milhões

www.esab.edu.br 140
de computadores sem que o criador do vírus tenha qualquer controle
sobre isso. A seguir, veremos outro tipo de risco às informações em um
computador: a perda acidental de dados.

23.3 Perda acidental de dados


De acordo com Tanenbaum (2010), embora o risco de invasores nocivos
parecer mais grave que a perda acidental de dados, é muito mais comum
dados serem perdidos de forma acidental.

Dados podem ser perdidos acidentalmente de diversas formas, entre


elas estão fenômenos naturais, erros de hardware ou de software e erro
humano. É normal que fenômenos naturais (como chuvas, incêndios,
terremotos etc.) ou até mesmo a degradação dos equipamentos ao longo
do tempo possa causar a perda de dados. Computadores não são feitos
de materiais altamente resistentes, mas o risco desses fenômenos causar
perda de informação sempre está presente.

É possível também que dados sejam perdidos por defeitos nos


componentes de hardware do computador ou erros em programas. Um
dos maiores riscos está em possíveis falhas de leitura de discos rígidos,
pois é neles que ficam armazenados todos os dados.

Por fim, o erro humano também é um risco para os dados em um


computador. Os usuários geralmente têm livre acesso aos dados que lhes
pertencem e equívocos podem ocorrer, causando a possível perda de dados.

Logo, é necessário que todo SO forneça mecanismos para que os usuários


não percam seus dados mesmo na ocorrência de fenômenos naturais,
erros da máquina ou falha humana. A solução para a maioria desses
problemas está na realização de backups, que permitem que os dados
fiquem armazenados em mais de um local, aumentando a segurança
das informações. Todo SO moderno fornece meios para que os usuários
realizem backup dos seus dados.

www.esab.edu.br 141
Terminamos, assim, esta unidade sobre o tópico de segurança e
confiabilidade de um SO. Vimos por que os SOs precisam se preocupar
com a segurança dos dados e estudamos várias ameaças possíveis aos SOs
e aos dados que eles gerenciam. Na próxima unidade, iremos finalizar
nossos estudos sobre sistemas operacionais. Até lá!

Saiba mais
Um dos objetivos de um SO é manter a
disponibilidade do sistema e o ataque de negação
de serviço é a maior ameaça ao cumprimento
desse objetivo. Para compreender melhor o que
é esse ataque de negação de serviço, faça uma
leitura do material disponível clicando aqui.

www.esab.edu.br 142
Considerações sobre sistemas
24 operacionais
Objetivo
Articular os principais fundamentos de sistemas operacionais,
abordando suas inter-relações.

Ao longo da disciplina, estudamos os fundamentos de sistemas


operacionais. Todo SO possui um conjunto básico de funcionalidades
que ele precisa realizar para cumprir seus dois principais objetivos:
permitir que os programas usem de forma simplificada todos os recursos
da máquina e gerenciar a utilização desses recursos mesmo quando vários
programas desejam utilizá-los ao mesmo tempo.

Nesta unidade, iremos finalizar nossos estudos a respeito dos SOs, discutir
a importância do estudo de sistemas operacionais e conhecer uma visão
geral a respeito de todos os fundamentos que estudamos. Apoiaremos
nossos estudos nos trabalhos de Tanenbaum (2010), Silberschatz, Galvin e
Gagne (2001) e Deitel, Deitel e Steinbuhler (2005). Para começar, vamos
ver uma visão geral de um sistema operacional.

24.1 Visão geral de um sistema operacional


Para Tanenbaum (2010), e conforme estudamos nas unidades 1 e 4,
um SO possui duas funções principais: servir como uma extensão do
hardware, facilitando o acesso dos programas aos recursos da máquina
e gerenciar os recursos da máquina, pois eles são limitados e diversos
programas os usam simultaneamente.

Porém, para entendermos como o SO pode ser uma extensão do


hardware, precisamos primeiro entender que hardware é esse. O principal
componente de hardware é o processador. Ele tem a função de executar
instruções em linguagem de máquina. Porém, de onde vêm essas
instruções? Elas fazem parte de cada um dos programas do computador, e

www.esab.edu.br 143
deve existir algum mecanismo para que o processador possa ler e executar
cada uma das instruções de todos os programas do computador.

Todo computador possui também uma memória secundária, do tipo não


volátil, ou seja, uma memória que guarda os dados até mesmo quando
o computador é desligado. É nessa memória que ficam guardados os
programas de computador, logo, é de lá que o processador precisa ler as
instruções para executar. Mas como esses programas ficam armazenados
na memória sem que a memória vire uma bagunça? É preciso que haja
uma organização de todos os dados na memória secundária, para que o
processador saiba exatamente onde está cada instrução.

Um dos problemas da memória secundária é que ela é lenta. Por isso, existe
a famosa memória RAM, também chamada de memória principal, que é
do tipo volátil, ou seja, seus dados são perdidos quando o computador é
desligado. Porém, ela é uma memória muito mais rápida que a memória
secundária. Dessa forma, os programas podem ficar armazenados na
memória secundária e ser copiados para a memória principal quando
executados, para que o processador possa ler a, partir da memória
principal, cada uma das instruções do programa e assim executá-las.

Mas quem gerencia tudo isso? Quem organiza a memória secundária de


forma a armazenar milhares de programas? Quem gerencia a memória
principal de forma a guardar as instruções de cada programa em
execução? Quem diz para o processador em qual lugar da memória estão
as instruções que ele deve executar ou qual programa ele deve executar
em determinado momento?

O SO é a resposta para todas essas perguntas. Sem o SO a memória


secundária é apenas uma memória cheia de dados que não fazem sentido;
a memória principal é também apenas uma memória com dados e
instruções de vários programas; e o processador é apenas um componente
de hardware que executa instruções.

De acordo com Tanenbaum (2010) e Silberschatz, Galvin e Gagne


(2001), o SO possui um sistema de arquivos que gerencia todos os
dados que estão na memória secundária, organizando-os de forma
que o usuário possa acessá-los, modificá-los ou executá-los, caso sejam

www.esab.edu.br 144
programas. O SO também gerencia a memória principal, definindo
espaços de endereçamento para cada programa, que são trechos da
memória que cada programa pode utilizar conforme desejar, sem ser
afetado pelos outros programas e também sem que os outros programas
sejam prejudicados.

De acordo com Deitel, Deitel e Steinbuhler (2005) e Tanenbaum


(2010), o SO também gerencia a execução de cada programa, criando
uma abstração chamada de processo. Um processo é como chamamos
um programa quando está sendo executado pelo processador. As
instruções, os dados e as informações importantes ficam na memória
principal, e o processador acessa essas informações para poder executar
o programa. O SO gerencia todos os processos na memória e também
gerencia o trabalho do processador ao executar cada um dos programas.

Porém, um computador não possui só processador e memórias.


Há também uma série de dispositivos de E/S que se conectam e se
comunicam com o computador e com os diversos programas contidos
nele. Cada dispositivo possui suas funcionalidades específicas e seu modo
de funcionamento particular. Porém, graças ao SO, todos os programas
podem facilmente utilizar os recursos desses dispositivos. O SO possui o
que chamamos de drivers de dispositivos, que são pequenos programas
de computador que gerenciam o uso dos dispositivos comunicando-se
diretamente com seus controladores.

O SO então pode ser visto como o grande controlador do computador.


Ele é o principal programa do computador e gerencia a execução de
todos os outros. A razão para que hoje em dia seja simples criar um
programa de computador e executá-lo deve-se principalmente ao SO.
Por ser uma extensão da máquina, ele permite que todos os programas
utilizem facilmente qualquer recurso da máquina. E por ser um
gerenciador de recursos, graças a ele é possível ter milhares de programas
na memória secundária, dezenas de programas em execução ocupando a
memória principal e também essas mesmas dezenas de programas sendo
executados pelo processador. Em outras palavras, o SO permite um justo
compartilhamento de todos os recursos da máquina por parte de todos
os programas.

www.esab.edu.br 145
Um SO é um programa de computador extremamente complexo e que
leva anos para ficar pronto. Por essa razão, existem poucos e não se criam
muitos SOs novos atualmente. Então, qual é a importância de estudar esses
sistemas operacionais? A seguir, confira a resposta para essa pergunta.

24.2 Importância do estudo de sistemas operacionais


Embora não se criem muitos SOs novos atualmente e mesmo que o
profissional na área de Sistemas de Informação não participe do projeto
de novos SOs, nem se envolva na manutenção de um SO já existente,
entender como um SO funciona pode ser de grande importância.

Todo sistema de informação é executado em conjunto com um sistema


operacional. O SO faz parte da execução de qualquer sistema de
informação. Toda decisão tomada durante o projeto de um sistema de
informação precisa levar em consideração aspectos referentes ao SO. Por
exemplo, se o novo sistema de informação precisa realizar várias tarefas
em paralelo, é possível criar novas threads para executar cada tarefa? Essas
threads podem compartilhar dados? A resposta a essas questões influencia
o projeto do sistema e depende totalmente de como o SO foi projetado.

Outro exemplo é o caso de um sistema de informação fazer uso de um


dispositivo de E/S peculiar, como uma placa de captura de imagem. Placas
de captura de imagem não são muito comuns e é possível que o SO não
possua drivers de dispositivo que consigam compreender a forma com que
a placa trabalha. Nesse caso, se tornaria impossível a utilização da placa com
esse SO. Logo, é importante que os projetistas do sistema de informação
conheçam bem o funcionamento do SO e também suas limitações.

Nesta unidade, você estudou a respeito da importância de se conhecer


os fundamentos dos sistemas operacionais. Você, como estudante
de Sistemas de Informação, consegue identificar as vantagens que o
estudo de SO pode trazer para a sua carreira? Você, como usuário de
computadores, já enfrentou alguma situação em que o seu conhecimento
a respeito de SO foi importante?

www.esab.edu.br 146
Terminamos assim nossa disciplina, na qual pudemos obter uma visão
geral do que é um sistema operacional e pudemos entender qual é a
importância de se estudar os fundamentos de um SO.

Atividade
Chegou a hora de você testar seus conhecimentos
em relação às unidades 17 a 24. Para isso, dirija-se ao
Ambiente Virtual de Aprendizagem (AVA) e responda
às questões. Além de revisar o conteúdo, você estará
se preparando para a prova. Bom trabalho!

www.esab.edu.br 147
Resumo

Nas últimas seis unidades da disciplina, estudamos diferentes aspectos


de um SO. Primeiro, vimos como o SO realiza o gerenciamento de
arquivos, aprendendo o que são arquivos e diretórios e como eles ficam
armazenados na memória secundária. Vimos também o que é um
sistema de arquivos e como ele funciona. Por fim, estudamos algumas
particularidades de sistemas de arquivos conhecidos, como o do Unix e o
do MS-DOS.

Estudamos também como é realizado o gerenciamento das operações


de E/S. Aprendemos que todo dispositivo de E/S possui uma parte
mecânica e uma eletrônica, que essa parte eletrônica é chamada de
controlador do dispositivo e que ela é a responsável por conectar
o dispositivo ao computador. Vimos que o SO possui drivers de
dispositivos, que são programas de computador que fazem parte do
SO e realizam a ponte entre os programas do usuário e o controlador
dos dispositivos. Estudamos também diferentes formas de realizar a
transmissão de dados entre programas e dispositivos, como o uso de
polling, interrupções ou DMA.

Por fim, estudamos tópicos extras a respeito de SOs, como aspectos


de segurança e confiabilidade, e vimos por que o tópico de segurança
é importante para um SO e com que tipos de ameaças um SO precisa
se preocupar para manter a segurança dos dados e dos usuários. Para
finalizar os estudos, obtivemos uma visão geral de como é um SO e de
qual é a importância de estudarmos os seus fundamentos.

www.esab.edu.br 148
Glossário

Abstração
Simplificação ou redução de um conceito complexo, de forma a facilitar
sua compreensão ou utilização. R

API
Do inglês Application Programming Interface, ou Interface de
Programação de Aplicações, consiste em uma série de interfaces que
permitem que aplicações realizem funções complexas de forma simples.
R

Assembly
Linguagem de programação primitiva e bastante parecida com a
linguagem de máquina. Ainda é usada atualmente por sistemas
operacionais para controlar alguns componentes de hardware. R

Barramento
Conjunto de fios condutores de energia elétrica usados para a
comunicação entre componentes de hardware de um computador. R

Batch
Tipo de sistema primitivo no qual um conjunto de programas ou
funcionalidades eram executadas em conjunto, não mais uma a uma,
como ocorria com tecnologias mais antigas. R

Backup
Cópia de segurança de um dado ou de um conjunto de dados,
armazenada em um local separado dos dados originais. R

www.esab.edu.br 149
Buffer
Região da memória física usada para armazenar, temporariamente, dados
que estão sendo transportados de um local para outro. R

Bug
Erro no código de um programa que causa o mau funcionamento do
programa. R

Caminho de arquivo
Identificação única de cada arquivo ou diretório em um sistema de
arquivos, com base na posição do arquivo e diretório dentro do sistema,
em relação à raiz da árvore. R

Cartão perfurado
Cartão de papel em que comandos para a máquina eram codificados
através da criação ou não de furos em locais específicos do papel. R

Chamada de sistema
Ou system call, é uma função do SO que processos do usuário ou do
próprio SO podem chamar para realizar tarefas específicas, as quais
apenas o SO pode realizar. R

Circuitos integrados
Conjunto de diversos transistores que fazem parte de um único circuito,
capaz de realizar uma funcionalidade específica. R

Confidencialidade dos dados


Garantir que um arquivo ou uma informação não possa ser acessada por
usuários sem autorização. R

Contador do programa
Dado que informa qual é a próxima instrução de um programa que o
processador deverá executar. R

www.esab.edu.br 150
Endereço físico
Endereço de memória que existe fisicamente no hardware da memória.
R

Endereço de memória
Espaço unitário na memória principal onde é possível armazenar algum
dado. R

Endereço virtual
Endereço de memória abstrato usado por um programa de computador
para armazenar algum dado. Esse endereço pode ser mapeado para
qualquer endereço físico da memória, dependendo da gerência realizada
pelo SO. R

Fortran
Uma das primeiras linguagens de programação, usada até hoje em
aplicações científicas. R

GUI
Do inglês Graphic User Interface, ou Interface Gráfica do Usuário, é
uma forma de interface onde o conteúdo do computador é mostrado
para o usuário de forma gráfica, capaz de receber comandos do usuário
relacionados ao conteúdo mostrado na tela. R

Hierarquia de memória
Conjunto de memórias de um computador, que contempla desde os
registradores que ficam junto da UPC até as unidades de armazenamento
não volátil. R

Integridade dos dados


Garantir que um arquivo ou uma informação não possa ser manipulada e
alterada por usuários sem autorização. R

www.esab.edu.br 151
Interface
Meio de comunicação entre duas partes. R

Ken Thompson
Enquanto funcionário da Bell Labs, projetou e criou o sistema
operacional Unix junto com Dennis Ritchie e outros. R

Kernel híbrido
Tipo de kernel que combina características de um kernel monolítico e de
um microkernel. R

Kernel monolítico
Kernel em que todas as funcionalidades do sistema operacional estão
juntas executando em modo kernel. R

Largura de banda
Quantidade de bits transmitidos por segundo. R

Linus Torvalds
Criador do sistema operacional Linux, um dos principais sistemas
operacionais da atualidade. R

Memória virtual
A utilização de um espaço de endereçamento virtual dividido em blocos
onde nem todos precisam estar presentes na memória simultaneamente
para um programa funcionar. R

Microkernel
Kernel em que apenas as funcionalidades mais básicas do sistema
operacional fazem parte do kernel e executam em modo kernel; as outras
funcionalidades são separadas e tratadas como aplicações em modo
usuário. R

www.esab.edu.br 152
Modo kernel
Modo de execução de um software em que ele possui total acesso a todos
os recursos de hardware. Por segurança, apenas o sistema operacional
executa em modo kernel. R

Multiprogramação
Característica de um sistema de permitir a execução de mais de uma
tarefa simultaneamente. R

Multithreading
Sistema em que é possível um único processo possuir mais de uma thread
de execução. R

Negação de serviço
Tipo de ataque que ameaça a disponibilidade do sistema, em que os
recursos da máquina são sobrecarregados a ponto de fazer com que a
máquina não consiga mais realizar suas funções normalmente. R

Núcleos (de UPC)


Também chamados de cores, são unidades de processamento capazes de
executar instruções da arquitetura da máquina. Uma UPC hoje possui
um ou mais núcleos, o que permite a execução de diversas instruções da
máquina ao mesmo tempo. R

PCB
Do inglês process control block, ou bloco de controle do processo, é a
representação de um processo na estrutura interna de controle do sistema
operacional. R

www.esab.edu.br 153
Pseudoparalela
Modelo de execução de processos em que, em um computador com um
único núcleo de processamento, apenas um processo é executado de cada
vez, mas todos os processos são executados aos poucos – compartilhando,
assim, o processador e dando a impressão de que estão sendo executados
paralelamente. R

Quantum
Em sistemas em que o escalonamento é preemptivo, é o intervalo de
tempo máximo durante o qual é permitido a um processo executar. R

Registrador-base
Registrador que indica em qual endereço físico da memória inicia o
espaço de endereçamento de um programa. R

Registrador-limite
Registrador que indica em qual endereço físico da memória termina o
espaço de endereçamento de certo programa. R

Swapping
A ação de tirar um programa da memória principal e salvá-lo em disco
sem finalizar seu processo, mas liberando espaço na memória para que
outro programa comece a ser executado. R

Transistor
Componente eletrônico condutor de energia elétrica, capaz de amplificar
ou reduzir um sinal elétrico. R

Unix
Sistema operacional criado por Ken Thompson, Dennis Richie e outros,
durante a terceira geração de sistemas operacionais e que se tornou a base
para a criação de diversos outros sistemas, como o Linux e os sistemas da
Apple. R

www.esab.edu.br 154
Referências

DEITEL, H.; DEITEL, P.; STEINBUHLER, K. Sistemas Operacionais. 3. ed.


São Paulo: Pearson, 2005.

SILBERSCHATZ, A.; GALVIN, P. B.; GAGNE, G. Sistemas operacionais:


conceitos e aplicações. Rio de Janeiro: Campus, 2001.

TANENBAUM, A. S. Sistemas operacionais modernos. 3. ed. São Paulo:


Prentice Hall, 2010.

www.esab.edu.br 155

Você também pode gostar