Você está na página 1de 55

Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4

1 Introdução aos Sistemas Operativos


1.1 O que é um sistema operativo (SO)
Um sistema operativo é um programa que actua como um intermediário entre o utilizador de
um computador e o hardware do computador.
Objectivo do sistema operativo:
 Criar um ambiente no qual o utilizador possa executar programas.
 Facilitar a utilização do computador.
 Utilizar o hardware do computador de forma eficiente.
Pode-se ver um computador como sendo composto de: hardware, sistema operativo,
programas e utilizadores.
O hardware (CPU, memória, dispositivos de entrada/saída, etc.) fornece os recursos básicos
do computador. Os programas (compiladores, bases de dados, jogos, programas de gestão,
etc.) utilizam os recursos do computador para resolver os problemas dos utilizadores. Podem
existir muitos e variados utilizadores (pessoas, maquinas e outros computadores) para resolver
vários tipos de problemas. Desta forma existem vários tipos de programas. O SO controla e
coordena o uso do hardware entre os vários programas que serão executados para os diversos
tipos de utilizadores. Um SO pode assim ser visto como um gestor de recursos e também como
um programa de controlo.
Como se pode ver não existe uma definição exacta e universalmente aceite do que é um SO,
porque não existe uma definição concreta do que faz parte de um SO. Podemos considerar que
tudo aquilo que um produtor de software fornece quando se encomenda um SO faz parte do
sistema operativo. Mas até isto esta em abertol…

Utilizador 1 Utilizador 2 Utilizador n

Compilador editor de texto base de dados

programas

Sistema Operativo

Hardware do Computador

Fig. 1.1 - Visão abstracta dos componentes de um computador

Evolução histórica
Os primeiros computadores (inícios da década de 1950) não dispunham de nenhum
software com as funcionalidades que hoje atribuímos aos sistemas operativos. O objectivo
principal nessa altura era a fiabilidade do hardware assim como o seu desempenho.
Os primeiros computadores eram máquinas enormes que eram controladas a
partir de uma consola. O programador (que também era o operador do computador) escrevia
o programa e 'operava' o programa directamente da consola. Primeiro o programa era
carregado manualmente em memória através da utilização dos interruptores da consola (uma
instrução de cada vez), ou através de cartões perfurados. Após isto o operador introduzia o
endereço inicial para execução do programa. À medida que o programa era executado o
operador podia monitorar o estado do mesmo através da observação das lâmpadas da
consola. Se fossem detectados erros o operador/programador podia parar a execução do
_________________________________________________________________________
Eng AACucko 2023 Página 1
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
programa, examinar o conteúdo da memória e dos registos e depurar (debug) o programa
directamente da consola. As saídas (output) eram impressas em papel ou em cartões perfurados.
Com o tempo foram aparecendo desenvolvimentos ao nível do software e hardware,
como por exemplo impressoras e fitas magnéticas. Começaram também a aparecer os
assemblers, loaders e linkers de forma a facilitar a programação. Apareceu também o
conceito de biblioteca de funções. As funções comuns podiam ser copiadas para novos
programas sem ser necessária a sua reescrita. Era o início da reutilização de software.

1.2.1 Monitor de controlo


A primeira aproximação ao SO moderno caracterizou-se pela realização de um programa
utilitário designado de monitor que permitia ao utilizador carregar os seus programas em
memória, editá-los e verificar a sua execução. Cada utilizador dispunha de uma quota de
tempo para utilização do computador e este estava completamente à sua disposição durante
aquele intervalo de tempo.
Um Monitor é constituído tipicamente por um conjunto de utilitários que facilitam a interacção com a
máquina:
 Interpretador de uma linguagem de comando que permite executar os restantes utilitários
 Compilador
 Tradutor de linguagem simbólica (Assembler)
 Editor de ligações (Linker)
 Carregador de programas em memória (Loader)
 Rotinas utilitárias para controlo de periféricos: consola; leitor de cartões;
leitor/perfurador de fita de papel; bandas magnéticas
Alguns sistemas operativos recentes trabalham de uma forma muito semelhantes a estes primeiros
antepassados... (MS-DOS, Spectrum, etc.)

1.2.2 Tratamento em Lotes (Batch)


O sistema de funcionamento anterior era ineficiente uma vez que só permitia um utilizador de
cada vez. Além disso muitas vezes o processador central do computador (CPU) estava inactivo à
espera de um comando do utilizador ou do termino de uma operação por parte de um periférico.
Uma forma de optimizar estes tempos consistiu na introdução de capacidades de
sequenciamento automático de trabalhos no monitor. Assim os computadores começaram a
tratar lotes de programas automaticamente. O monitor executava os programas
sequencialmente, uns após outros e sem paragem, e no fim os resultados (outputs) eram
disponibilizados aos programadores.
A característica fundamental de um sistema de tratamento em lotes é a falta de
interacção entre o utilizador e o programa enquanto este está a ser executado. O
programa (trabalho) é preparado e submetido. Algum tempo depois (minutos, horas
ou dias) aparece o output. O intervalo entre a submissão e o fim do trabalho depende
da computação a efectuar, de atrasos no carregamento do programa ou de acessos a
periféricos.
A evolução para sistemas tipo batch com sequenciamento automático de trabalhos tinha
como objectivo a melhoria do desempenho. Mesmo após a introdução desta técnica
grande parte do tempo o CPU continuava 'parado', nomeadamente sempre que havia
necessidade de aceder a periféricos bastante mais lentos (leitores de cartões ou impressoras).
Uma solução para a inadequada utilização da CPU consistiu em efectuar a recolha dos dados
num computador auxiliar onde eram lidos, para uma banda magnética, os cartões dos

_________________________________________________________________________
Eng AACucko 2023 Página 2
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
diversos trabalhos. O operador colocava em seguida a banda no computador central e este
executava os programas, produzindo igualmente os ficheiros de saída para outra banda que,
por sua vez, era tratada por um computador mais pequeno para optimizar o tempo de impressão.
Este sistema de tratamento por lotes, dos anos 50, rapidamente evoluiu. Os periféricos
começaram a poder executar operações autónomas, avisando o processador do fim da sua
execução através do mecanismo de interrupções. A grande evolução resulta da possibilidade
de notificar assincronamente o processador de que uma dada operação terminou. As
operações de entrada/saída podem prosseguir em paralelo com a execução de um programa
que apenas é interrompido para iniciá-las e para tratar a sua terminação.
Os periféricos de armazenamento evoluem deixando de ser meros dispositivos de acesso
sequencial (bandas magnéticas) para se tornarem verdadeiras memórias secundárias com
possibilidade de endereçamento aleatório (discos magnéticos).
Assim a banda magnética descrita anteriormente foi rapidamente substituída por
discos magnéticos de acesso aleatório. Nos novos sistemas que utilizam discos os
cartões são lidos directamente do leitor de cartões para o disco. A localização das
imagens dos cartões são guardadas numa tabela que o SO mantém.
Quando um trabalho é executado o SO satisfaz os seus pedidos de
input do leitor de cartões através da leitura do disco. Da mesma forma, quando o
trabalho requer que a impressora imprima uma linha a linha é copiada para um buffer do sistema
e depois escrita para o disco. Só quando o trabalho termina é que o
output é de facto enviado para a impressora. Esta forma de processamento designa-
se por spooling (simultaneous peripheral operation on-line). Resumindo, o spooling
consiste na utilização do disco como um buffer, para ler em avanço o mais possível
os dispositivos de input e para armazenar as saídas o mais possível até que os
dispositivos de output as possam aceitar.
O spooling permite a sobreposição de uma operação de entrada/saída (I/O) de um trabalho
com a computação de outro trabalho. Mesmo num sistema simples, o spooler pode estar a ler o
input de um trabalho enquanto imprime o output de outro trabalho. Durante este tempo outro
trabalho pode estar a ser executado, lendo os seus 'cartões' do disco e 'imprimindo' as suas
linhas de output em disco. Desta forma a técnica de spooling pode manter tanto o CPU como
os dispositivos de entrada e saída a trabalharem a níveis de desempenho muito superiores.
1.2.3 Multiprogramação
A técnica de spooling introduz uma estrutura de dados muito importante: a pool de trabalhos.
A técnica de spooling geralmente resulta na existência de vários trabalhos em disco à
espera de serem executados (pool). A existência de uma pool de trabalhos em disco permite
que o SO escolha qual o próximo trabalho a ser executado, de forma a optimizar a
utilização da CPU. Quando os trabalhos vêm directamente dos cartões ou das bandas
magnéticas não é possível executá-los numa ordem diferente da leitura. Os trabalhos têm que
ser executados sequencialmente, ou seja, o primeiro a entrar é primeiro a ser servido. No
entanto, quando vários trabalhos se encontram num dispositivo de acesso directo, tal como um
disco, o escalonamento dos trabalhos torna-se possível.
O aspecto mais importante do escalonamento de trabalhos é a possibilidade da
multiprogramação. Normalmente um único utilizador não consegue manter sempre a CPU e os
dispositivos de I/O sempre 'ocupados'. A multiprogramação aumenta a utilização da CPU
organizando os trabalhos de forma a que a CPU tenha sempre que possível trabalho para executar.
A ideia é a seguinte. O SO mantém vários trabalhos em memória num determinado momento.
Este conjunto de trabalhos é um subconjunto dos trabalhos que constituem a pool de
trabalhos (uma vez que o número de trabalhos que podem estar simultaneamente em memória
_________________________________________________________________________
Eng AACucko 2023 Página 3
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
é normalmente menor que o número de trabalhos que podem estar na pool de trabalhos). O SO
selecciona e começa a executar um dos trabalhos que está em memória. Eventualmente o
trabalho pode ter que esperar por alguma tarefa, tal como a instalação de uma banda, um comando
entrado via teclado, ou que uma operação de I/O termine. Num sistema que não seja
multiprogramado, a CPU ficaria parado. Num sistema multiprogramado,
o SO 'muda' para outro trabalho e executa-o. Quando esse trabalho precisa de esperar, a CPU
é outra vez 'desviado' para outro trabalho e assim sucessivamente. Eventualmente o primeiro
trabalho termina a sua espera e a CPU volta a executá-lo. Desde que exista sempre um trabalho
para ser executado a CPU nunca esta parada, ou seja, a utilização do computador é
aproveitada ao máximo.
Com a multiprogramação os SOs começam a tomar decisões pelos utilizadores (qual o próximo
trabalho a ser executado?). Com a multiprogramação a complexidade dos SOs aumenta. Todos
os trabalhos que entram no sistema têm que ser mantidos na pool. Esta pool contém todos os
processos que residem num dispositivo de armazenamento em massa à espera de serem
colocados na MP (memória principal). Se existem diversos trabalhos prontos para irem
para a MP mas não existe espaço para todos então o sistema tem que escolher quais os
que deverão ser carregados. Estamos a falar do principio do escalonamento de
trabalhos/processos.
Quando o SO selecciona um trabalho na pool deve-o carregar para a MP para este ser
executado. Pelo facto de ter vários programas em memória ao mesmo tempo o SO precisa de
ter mecanismos de gestão de memória.
Se o SO tem vários trabalhos prontos para correr ao mesmo tempo então deve escolher qual
deve ser executado. Este aspecto designa-se por escalonamento de tempo de CPU.
Saliente-se ainda que pelo facto de vários trabalhos serem executados concorrentemente
implica que se torna necessário gerir e em particular controlar a forma como estes comunicam
entre si e com o SO de forma apoderem partilhar recursos e não interferirem inadvertidamente entre
si.
1.2.4 Sistemas Interactivos
Um SO que permita multiprogramação por lotes (batch) consegue um elevado grau de utilização
efectiva de todos os recursos de um computador. No entanto este tipo de SO ainda tem algumas
desvantagens sob o ponto de vista do programador ou utilizador final, uma vez que este não pode
interagir com o seu programa enquanto este está a ser executado. Por exemplo, um programa
pode ter vários passos que dependem uns dos outros e requerem a intervenção do
utilizador ou ainda, o programador pode ter necessidade de verificar o seu programa enquanto
este executa (debug).
Assim uma evolução dos SOs multiprogramação foram os SOs multitarefa/interactivos. Neste tipo
de sistemas operativos vários trabalhos podem ser executados pelo CPU. A grande diferença é
que a frequência com que o sistema operativo muda entre tarefa a executar pelo CPU é tão
elevada que os utilizadores podem interagir com cada tarefa/trabalho enquanto estes estão a
correr.
Um sistema interactivo possibilita uma comunicação on-line entre o utilizador e o
sistema.
O utilizador de um sistema interactivo dá instruções ao SO ou programa directamente e
recebe as respostas imediatamente. É usual a utilização de um teclado para o input e de um
monitor (CRT = cathode-ray tube) para o output. Quando o SO termina a execução de um
comando vai procurar a próxima instrução ao leitor de cartões mas ao teclado do utilizador.
Se os utilizadores tiverem necessidade de aceder a dados e código de uma forma conveniente e
facilitada então o SO deve suportar um sistema de ficheiros on-line.
_________________________________________________________________________
Eng AACucko 2023 Página 4
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
Um SO interactivo permite que os utilizadores partilhem o computador simultaneamente.
Como cada acção ou comando num sistema multitarefa (ou seja de partilha de tempo de CPU ou
time-share) tende a ser curta, apenas uma pequena parte do tempo do CPU é necessária para
cada utilizador. Como o sistema muda rapidamente entre utilizadores, cada utilizador tem a
impressão de ter o sistema a trabalhar para ele em exclusivo.
O conceito da multitarefa foi demonstrado no inicio dos anos 1960 mas devido aos seus custos
(necessitavam de muitos dispositivos de I/O) só se tornaram comuns no inicio dos anos 1970.
Hoje em dia é comum a grande parte dos sistemas trabalharem em multitarefa e de forma
interactiva embora também ofereçam possibilidade de trabalho em batch.
Os SOs multitarefa são ainda mais complexos que os de multiprogramação. Tal como
nos de multiprogramação vários trabalhos podem estar simultaneamente em memória, o que
implica algum tipo de gestão e protecção de memória. Para que sejam obtidos tempos de
resposta razoáveis os trabalhos podem ter que ser trocados entre memória principal e disco (que
passa a servir de 'extensão' à memória principal). Uma técnica que permite atingir este
objectivo é a chamada memória virtual que permite a execução de um trabalho que pode
não estar completamente em memória. Assim os programas podem ser maiores que a memória
física do computador. Desta forma o programador pode-se abstrair das limitações da memória
física do computador. Os sistemas de multitarefa também devem providenciar um sistema de
ficheiros on-line. Este sistema de ficheiros pode residir num conjunto de discos; assim também
são necessárias características de gestão de discos. Como os sistemas multitarefa permitem a
execução concorrente também serão necessários mecanismos de escalonamento de tempo
de CPU. Para que a execução dos trabalhos se faça de forma prevista e ordenada o
sistema deve providenciar mecanismos para a sincronização de trabalhos e comunicação
entre estes.
1.2.5 Sistemas Paralelos
Grande parte dos sistemas actuais utilizam apenas um processador (CPU). No entanto a
evolução tem sido no sentido de SOs que tomam partido de vários processadores. Estes
sistemas têm mais do que um processador em comunicação, que partilham o barramento, o
relógio e algumas vezes a memória e os periféricos.
Uma das grandes vantagens destes sistemas é o aumento de desempenho do computador.
Os sistemas multiprocessador também podem permitir uma diminuição de custos em
comparação com os sistemas monoprocessados porque os processadores podem partilhar
periféricos.
Outra vantagem dos sistemas multiprocessados é o aumento de confiança num desempenho
sem falhas. Se as funções forem distribuídas de forma adequada entre os processadores então a
falha de um processador não implica a paragem de todo o sistema, apenas uma diminuição no
seu desempenho.
O tipo de multiprocessamento mais comum é o chamado multiprocessamento simétrico, no
qual cada processador corre uma cópia idêntica do sistema operativo. Estas cópias do sistema
operativo comunicam entre si conforme as necessidades. Nos sistemas de multiprocessamento
assimétrico a cada processador é atribuída uma tarefa distinta. Um processador mestre
controla todo o sistema; os outros processadores ou interrogam o processador central para
obterem instruções ou têm tarefas especificas atribuídas.

1.2.6 Sistemas Distribuídos


Outra linha de desenvolvimento actual é a da distribuição de computação entre vários
processadores. Ao contrário dos sistemas descritos anteriormente estes sistemas não
partilham memória nem relógio. Cada processador tem a sua memória local. Os processadores
comunicam entre eles através de linhas de comunicação, como barramentos de alta
_________________________________________________________________________
Eng AACucko 2023 Página 5
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
velocidade, redes locais ou até linhas telefónicas. Estes sistemas são usualmente designados por
sistemas distribuídos.
Os processadores num sistema distribuído podem variar em tamanho e função. Podem
incluir pequenos microprocessadores, estações de trabalho, minicomputadores, e
grandes computadores genéricos. Estes processadores são normalmente referidos por diversos
nomes tais como Sites ou nodes.
Algumas das razões que levam à construção de sistemas distribuídos são:
 Gestão de recursos. Se diversos Sites são conectados uns aos outros então um
utilizador de um Site pode utilizar os recursos disponíveis nos outros Sites, tais como
impressoras ou ficheiros. Em geral a partilha de recursos num sistema distribuído consiste
em mecanismos para partilha de ficheiros, processamento de informação em bases de dados
distribuídas, impressão de ficheiros em Sites remotos, utilização de hardware especial e outros
tipos de operações.
 Aumento da velocidade de computação, se uma determinada computação pode ser
dividida em parcelas de sub computações que podem correr concorrentemente então um
sistema distribuído deve permitir a sua distribuição entre vários Sites. Além disso se um
determinado Site estiver sobrecarregado de trabalho então parte do seu trabalho pode ser
movido para outros Sites menos sobrecarregados. A esta tarefa dá-se o nome de
balanceamento de carga.
 Segurança/estabilidade Se um Site falha num sistema distribuído os Sites restantes
devem poder continuar a correr. Se o sistema for composto de um grande número de
instalações autónomas então a falha de um sistema não deve afectar a parte restante. Se, por
outro lado, o sistema for composto por um número alargado de pequenas máquinas cada qual
responsável por uma determinada parte do sistema então a falha de um sistema pode afectar
a operação do sistema como um todo. De forma geral, se existir alguma redundância no
sistema, então o sistema distribuído pode continuar mesmo após algum dos seus Sites ter
falhado.
 Comunicação Existem várias razões para que os programas que correm num sistema
distribuído necessitem de trocar dados, mesmo aqueles que correm em computadores/Sites
diferentes. A comunicação entre Sites num sistema distribuído é efectuada através de uma rede.

1.2.7 Sistemas Tempo-Real


Outro tipo especifico de SO é o chamado SO de tempo real. Um sistema tempo real é
utilizado sempre que existem requerimentos rígidos ao nível da operação de um processador
ou em termos de processamento de dados. Estes sistemas são usualmente utilizados como
dispositivos de controlo numa aplicação especifica e dedicada. Existem sensores que enviam
os dados para o computador. O computador analisa os dados e em função deles possivelmente
ajusta controlos de forma a alterar o input do sensor. Exemplos de sistemas tempo real são:
controlo de experiências cientificas, sistemas de imagem para medicina e sistemas de controlo
industrial, sistemas de controlo de injecção de combustível para motores de automóveis,
controladores de electrodomésticos e sistemas de armamento.
Considera-se que um sistema tempo real funciona correctamente só se retornar o resultado
correcto dentro de determinados limites temporais. Nos sistemas multitarefa (partilha de tempo)
apenas é desejável a resposta rápida. Nos sistemas batch não existem quaisquer tipos de
restrições temporais.
Os sistemas de tempo real podem serem do tipo hard e os soft.
Os sistemas hard garantem que as tarefas criticas possam ser terminadas no tempo
previsto. Este objectivo requer que todos os atrasos no sistema estejam limitados,
desde o tempo que leva a ler dados armazenados ao tempo que leva a que o SO termine algum
_________________________________________________________________________
Eng AACucko 2023 Página 6
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
pedido. Estes requisitos determinam as funcionalidades que estão disponíveis nos sistemas do
tipo hard. Normalmente não se encontram nestes sistemas dispositivos de armazenamento
secundário, sendo que os dados ficam armazenados em memória do tipo ROM. Muitas
características de sistemas operativos avançados também não estão disponíveis, uma vez que
tendem a separar o utilizador do hardware e essa separação resulta num aumento na
incerteza do tempo que leva uma operação a ser executada (por exemplo a memória
virtual).
Assim os sistemas operativos mais comuns e genéricos não suportam este tipo de
tempo real.
Um sistema tempo real do tipo soft mantém praticamente as características dos SOs usuais só
que as tarefas de tempo critico têm uma prioridade superior às outras tarefas. Essa
prioridade mantém-se ate a tarefa terminar. Os sistemas soft estão mais limitados em termos
de utilização que os sistemas hard uma vez que não garantem o tempo de execução das tarefas
criticas. Estes sistemas não podem ser utilizados para controlar robots ou máquinas
industriais. Podem ser utilizados noutras áreas como a multimédia, a realidade virtual ou
projectos de carácter cientifico. Estes sistemas necessitam de características de sistemas
operativos avançados que os sistemas hard não implementam.

_________________________________________________________________________
Eng AACucko 2023 Página 7
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4

2 Arquitectura básica de um computador


2.1 Funcionamento de um computador
Rotinas Um computador consiste numa CPU e num certo numero de
controladores de dispositivos que estão ligados a um barramento comum que dá
acesso à memória partilhada.
Um controlador de memória controla o acesso dos vários dispositivos e
CPU à memória
No arranque o computador carrega o boostrap program que inicializa todos
os aspectos do sistema e carrega o SO e dá inicio à sua execução. O SO fica à
espera da ocorrência de um evento/sinal via uma interrupção de hardware ou
software (system call).
Eventos que podem gerar uma interrupção: finalização de uma operação de
IO; divisão por zero; acesso inválido à memória; requisição de um serviço do
sistema operativo.
Quando o CPU é interrompido, para o que está a fazer e transfere a execução
para um local predefinido (vector de interrupções). Este local contém o endereço
inicial da rotina de serviço do sistema operativo que responde a esse tipo de
interrupção.
O MS-DOS e o UNIX funcionam através de vectores de interrupção.
Usualmente o serviço de interrupções é desactivado enquanto o SO responde
a uma interrupção...
A maior parte dos sistemas operativos modernos é interrupt driven.
2.2 Estrutura de I/O (Entrada/Saída)
2.2.1 Interrupções de I/O
Para começar uma operação de IO o CPU carrega os devidos registos do
controlador do dispositivo. O controlador do dispositivo examina o conteúdo
desses registos para determinar o que deve fazer. Por exemplo, se for um pedido
de leitura o controlador inicia a transferência de dados desde o dispositivo para o
buffer local. Assim que a transferência estiver completa o controlador informa o
CPU que finalizou o pedido (normalmente através de uma interrupção ao CPU).
Existe o IO Síncrono (a instrução wait faz com que o CPU espere ate a
próxima interrupção). A CPU só processa um pedido de IO de cada vez.
Existe o IO Assíncrono. Neste caso o CPU tem que lidar com muitos
pedidos de IO ao mesmo tempo. Por isso o SO usa uma tabela contendo uma
entrada para cada dispositivo de IO. Como cada dispositivo pode ter vários
pedidos de vários programas é necessária uma lista de pedidos por cada uma das
entradas da tabela acima descrita.
A grande vantagem do IO assíncrono é o aumento da eficiência do sistema.
2.2.2 Estrutura de DMA (Direct Memory Access)
Para resolver problemas como por exemplo a interrupção do CPU por cada
transferência de um caracter de um dispositivo existe uma técnica de
_________________________________________________________________________
Eng AACucko 2023 Página 8
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
funcionamento para dispositivos rápidos que se designa de DMA (Acesso Directo
a Memória).
Depois de inicializar os buffers, ponteiros e contadores do dispositivo de IO,
o controlador transfere um bloco de dados completo para a memória sem
intervenção do CPU. Apenas é gerada uma interrupção no final de cada
transferência de bloco (ao invés de uma interrupção por byte nos dispositivos
mais lentos).
2.3 Estrutura de Armazenamento
A CPU só executa programas que estão na MP.
Normalmente e MP é demasiado pequena para conter todos os programas e
dados.
A MP é volátil (ou seja, perde todo o seu conteúdo quando se desliga o
computador da corrente).
Assim os computadores fornecem memória secundária persistente que
funciona como uma extensão da MP (usualmente discos magnéticos)
2.3.1 Memória Principal
A MP e os registos do processador são os únicos tipos de armazenamento
que o CPU pode aceder directamente. Assim qualquer instrução que for
executada ou qualquer dado tem que estar nestes tipos de armazenamento.
Para tornar mais eficiente o acesso aos dispositivos alguns computadores
permitem uma técnica que se designa de mapeamento de memória de IO na qual a

memória dos dispositivos é mapeada na memória central e assim a CPU


consegue’ aceder directamente aos dispositivos. Escritas e leituras da CPU neste
tipo
de memória causa o envio ou recepção de dados do dispositivo de forma
automática.
 Um exemplo disto são dispositivos de acesso muito rápido como é o caso
das placas gráficas. Outro exemplo é as portas série dos computadores.
Como os registos estão ‘dentro’ do próprio CPU o acesso a estes pode ser
efectuado num ciclo de relógio. O mesmo não acontece para a MP que pode estar
ligada ao barramento do sistema e o seu acesso demorar vários ciclos de relógio.
Neste caso normalmente a CPU está a ‘empatar’ até que o acesso se complete.
Para resolver esta situação pode-se introduzir memória de acesso rápido entre o
CPU e a memória principal. Um buffer de memória para conseguir isto é
designado Cache.
2.3.2 Discos Magnéticos
Os discos magnéticos têm controladores que fazem a gestão da interacção entre
o processador e o disco. O controlador recebe instruções da CPU e executa-as
sobre o disco magnético. Alguns controladores têm cache que permite conter os
dados de escrita e leitura mais recentes. Se os dados estiverem na cache a
necessidade de aceder ao disco é diminuída.
_________________________________________________________________________
Eng AACucko 2023 Página 9
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4

2.4 Hierarquia de Armazenamento


Os diversos dispositivos de armazenamento possíveis de encontrar num computador
podem ser organizados de acordo com a sua velocidade e custo. Os níveis mais altos
são rápidos mas caros. Nos mais baixos o custo por byte é menor mas o tempo de
acesso aumenta. Note-se que para além destes factores deve-se contar com a
característica de volatilidade.
Volátil Não-Volátil
Registos Discos Magnéticos
Cache Discos Ópticos
Memória Principal Cassetes Magnéticas
Discos Electrónicos
2.4.1 Caching
O Caching é uma técnica muito importante na informática. A informação está
normalmente num determinada dispositivo de armazenamento. Quando é
necessária é copiada temporariamente para um tipo de memória mais rápida (a
cache). Assim quando é necessário aceder a alguma informação verifica-se
primeiro se esta está na cache. Podemos considerar que os registos do CPU são
uma forma de cache...
Como a cache tem um tamanho limitado é necessário ter uma gestão bastante
cuidada (pode ter implicações importantes ao nível do desempenho).
O movimento dos dados entre os diferentes níveis de hierarquia pode ser
implícito ou explicito dependendo do tipo de hardware e das características do
sistema operativo.
Note-se que uma vez que as caches são copias é necessário manter regras de
coerência e consistência entre os vários níveis de armazenamento e entre as várias
caches...
2.5 Protecção de Hardware
Os primeiros computadores eram mono- utilizador. Os utilizadores tinham
controlo total sobre o sistema. À medida que os computadores evoluíram esse
controlo passou para os sistemas operativos.
Com a multiprogramação introduziu-se a partilha de recursos entre os vários
programas. Esta partilha melhorou a utilização mas também aumentou os
problemas. Neste cenário um problema num programa pode afectar os outros
programas!
Muitos erros de programação são detectados pelo hardware. Estes erros são
normalmente tratados pelo sistema operativo.
Um sistema operativo ‘correcto’ deve garantir que um programa não pode
causar erros nos outros programas.
2.5.1 Operação Dual-Mode

_________________________________________________________________________
Eng AACucko 2023 Página 10
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
Para que um computador funcione de forma adequada é necessário proteger
o SO e todos os programas e os seus dados de programas que não ‘funcionem’
de forma adequada.
A abordagem é a de que o hardware diferencie entre diversos modos de
execução. Pelo menos o modo de utilizador (user mode) e o modo de monitor
(monitor mode ~ supervisor mode ~ system mode ~ privileged mode). Um bit no
hardware pode indicar o modo actual. Com este bit pode-se distinguir tarefas do
SO das tarefas do utilizador. Sempre que é parte do SO que está a ser executado o
modo é de monitor. Quando o SO executa um programa passa para modo
utilizador.
Algumas instruções do CPU só são possíveis de executar em modo
supervisor. Assim se um programa tentar executa-las o hardware gera uma
interrupção que faz passar a execução para o sistema operativo.
2.5.2 Protecção de I/O
Um programa do utilizador pode estragar o normal funcionamento do
sistema através da execução de instruções de IO ilegais ou acedendo a locais de
memória do próprio SO.
Uma solução para que não existem operações IO ilegais é a de as tornarmos
operações privilegiadas. Assim um programa tem que fazer pedidos ao SO para
executar operações de IO.
2.5.3 Protecção de Memória
Para mantermos um sistema seguro temos pelo menos que proteger a área de
memória aonde se encontra o código do sistema operativo dos programas mal
comportados.
Este tipo de protecção é conseguida através do hardware. É possível
especificar o limite (intervalo) de endereços de memória possíveis para cada
programa em modo de utilizador. Assim cada endereço gerado em modo de
utilizador é verificado para ver se encontra dentro dos referidos limites. No caso
do endereço se encontrar fora dos limites o hardware gera uma interrupção que é
tratada pelo SO como um erro fatal.
Ao SO, que corre em modo supervisor é dados acesso ao seu espaço de
memoria e ao dos programas. Isto permite que o SO carregue os programas dos
utilizadores na memória dos utilizadores, limpe/liberte essa memória em caso de
erro, etc.
2.5.4 Protecção de CPU
Objectivo aqui é o de garantir que o SO nunca perde o controlo, por
exemplo quando os programas dos utilizadores entram em ciclo infinito
impedindo o SO de executar...
Uma forma de ultrapassar esta situação é fazer com que o hardware
interrompa a execução dos programas regularmente e passe o controlo para o SO.
Este poderá determinar que um programa está a demorar mais tempo que o que
era previsto e mata-lo.
_________________________________________________________________________
Eng AACucko 2023 Página 11
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
Este é o próprio conceito de time-sharing e de multiprogramação...

3 Arquitectura de um Sistema Operativo


3.1 Componentes do Sistema
Só é possível criar algo de tão complexo como um SO através da sua
divisão em partes mais pequenas. Cada uma dessas partes deve constituir uma
parte bem definida do sistema com inputs, outputs e função bem definida.
3.1.1 Gestão de Processos
Um programa não faz nada a não ser que as suas instruções sejam
executadas pelo processador.
Um Processo pode ser visto como um programa em execução.
Um processo necessita de recursos para ser executado: tempo de CPU,
memória, ficheiros, periféricos, etc. Estes recursos podem ser disponibilizados
ao processo quando ele é criado ou então são-lhe atribuídos em tempo de
execução.
Um Programa não é um Processo. Um programa é uma entidade passiva,
tal como o conteúdo de um ficheiro em disco. Um processo é uma entidade
activa, com um contador de programa (program counter) que especifica a
próxima instrução a ser executada.
A CPU executa uma instrução do processo de cada vez até o processo
terminar. Em cada momento apenas uma instrução do processo é executada. Se
existirem dois processos do mesmo programa estes são considerados como
duas unidades de execução diferentes.
Um processo é uma unidade de trabalho no SO. Um SO consiste numa
colecção de processos. Alguns desses são processos do sistema operativo (e
correm em modo supervisor) e outros são processos do utilizador (e correm em
modo de utilizador).
O SO é responsável pelas seguintes funções relativamente à gestão dos processos:
Criação e destruição de processos do sistema e dos utilizadores
Suspensão e reactivação de processos
Providenciar mecanismos para sincronização de processos
Providenciar mecanismos para comunicação entreprocessos
Providenciar mecanismos para gestão de deadlocks
3.1.2 Gestão da Memória Principal
Providenciar mecanismos para comunicação entreprocessos A MP é
geralmente o único dispositivo de armazenamento que o CPU consegue endereçar
directamente. Por exemplo, para que a CPU processe dados do disco magnético
é necessário que estes sejam transferidos primeiro para a memória principal
(através de chamadas de IO geradas pelo próprio CPU). Também as instruções
de um programa têm que estar em memória para serem executadas.
_________________________________________________________________________
Eng AACucko 2023 Página 12
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
Para que um programa seja executado este deve ser carregado em memória
(para um determinado endereço absoluto de memória). À medida que é executado
as suas instruções e dados também vêm de memória. Quando a sua execução
termina a sua memória está disponível para ser usada por outro programa.
 Para optimizar a utilização do CPU vários processos devem correr
simultaneamente no computador.
Para que o SO consiga efectuar isto existem vários esquemas de gestão de
memória (o melhor método de gestão de memória para um SO depende de várias
situações).
O SO é responsável pelas seguintes funções relativamente à gestão de
memória:
 Saber a cada momento que partes da memória estão a ser utilizadas e por
quem
Decidir que processos devem ser carregados em memória quando a
memória fica disponível
Reservar e libertar memória quando é necessário
3.1.3 Gestão do armazenamento secundário
Como a à MP memória principal é muito pequena para acomodar todos os
programas e dados (e os dados são perdidos quando se desliga o computador) é
necessária a existência de memória secundária (não volátil), usualmente sob a
forma de discos magnéticos.
O SO é responsável pelas seguintes actividades relativamente à gestão de disco:
 Gestão do espaço livre
Reserva de espaço
Escalonamento do disco (como o SO utiliza bastante o disco a utilização de
algoritmos menos adequados pode ter muita influência no desempenho global do
sistema)
3.1.4 Gestão do Sistema de IO
A gestão dos dispositivos de IO pelo sistema operativo está normalmente
escondida sob a forma de drivers. Estes drivers escondem a complexidade dos
periféricos de IO do próprio SO.
O subsistema de IO é normalmente constituído por:
Sistema de buffer-caching
Um interface geral para drivers de dispositivos
Drivers para dispositivos de hardware específicos
3.1.5 Gestão de Ficheiros
O armazenamento dos dados num computador pode ser efectuado em diversos
media. Cada um desses media tem características próprias. O SO deve
providenciar uma visão lógica uniforme relativamente aos dispositivos de
armazenamento.
Os ficheiros são a unidade lógica básica de armazenamento. Estes estão
_________________________________________________________________________
Eng AACucko 2023 Página 13
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
organizados em directorias.
Se vários utilizadores tiverem acesso a um ficheiro deve se poder controlar os
acessos assim como o que é que cada utilizador pode fazer.
O SO deve suportar as seguintes funcionalidades relativamente à gestão de
ficheiros:
Criação e destruição de ficheiros
Criação e destruição de directorias
Suportar primitivas para manipulação de ficheiros e directórios
Mapeamento dos ficheiros para armazenamento secundários
Backup de ficheiros em dispositivos de armazenamento não voláteis
3.1.6 Sistema de Protecção
Como o SO corre vários processos concorrentemente é necessário a existência
de mecanismos de protecção…
Por exemplo, o endereçamento de memória via hardware assegura que um
processo só pode executar no seu espaço de endereçamento. O timer assegura
que nenhum processo pode obter o controlo do CPU (só o SO). Os utilizadores
não podem executar directamente operações de IO.

3.1.7 Comunicações (Rede)


Um sistema distribuído é uma colecção de processadores que não partilham
memória nem relógio. Em vez disso os processadores têm a sua memória local e
comunicam entre si via linhas de comunicação (redes locais, linhas telefónicas,
etc.).
O desenho da rede de comunicação deve ter em conta estratégias de
encaminhamento e ligação assim como problemas de contenção (replicação de
dados…) e segurança.

3.1.8 Interpretador de comandos


Um dos programas do SO mais importante é o chamado interpretador de
comandos que não é mais que o interface entre o utilizador e o SO.
Nalguns SO, como o DOS e o UNIX, o interpretador de comandos é um
programa especial que é executado automaticamente no final do arranque do
sistema (DOS)
ou sempre que um utilizador 'entra' no sistema (UNIX).
O interpretador de comandos é a forma que o utilizador tem de executar
programas através de comandos…
Os comandos permitem fazer a gestão e trabalhar com processos, IO,
armazenamento, memória, sistema de ficheiros, protecção, comunicação, etc.
Em alguns sistemas esta interface com utilizador assume uma forma gráfica,
como no Windows ou no Macintosh.

_________________________________________________________________________
Eng AACucko 2023 Página 14
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4

4. Arquitectura de um Sistema Operativo


4.1 Serviços de um Sistema Operativo
O SO disponibiliza alguns serviços aos programas e utilizadores para facilitar a utilização do
computador.
Esses serviços podem variar entre Sistemas.
Algumas das classes de serviços mais usuais são:
 Execução de programas
 Operações de IO
 Manipulação do sistema de ficheiros
 Comunicação. Entre processos no mesmo computador ou processos em computadores
diferentes. Normalmente estes serviços são implementados através de técnicas de memória
partilhadas ou de envio de mensagens.
 Detecção de erros
 Outro conjunto de serviços existe para assegurar uma operação eficiente do SO:
 Reserva de recursos (quando se tem múltiplos utilizadores ou múltiplos processos)
 Contabilização (para efeitos estatísticos e de afinamento do SO)
 Protecção e Segurança (múltiplos utilizadores, acessos indevidos, etc.)

4.2 System Calls


 As system calls são o interface entre os
processos e o sistema operativo.
 Estas funções são acessíveis via instruções
Assembly ou então via bibliotecas de funções de
linguagens de alto nível (C, Pascal, etc).
 Os parâmetros para as system calls podem
ser passados por registos ou por stack ou por uma zona
de memória que vai especificada num registo.
 As chamadas ao SO podem ser divididas
em 5 grupos.

4.2.1 Controlo de processos e trabalhos


End, abort
Load, execute
Create process, terminate process
Get process attributes, set process attributes
Wait for a time
Wait event, signal event (um sinal trap - sinal de software -após cada instrução do CPU
permite implementar debuggers…)
Allocate and free memory
_________________________________________________________________________
Eng AACucko 2023 Página 15
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
4.2.2 Manipulação de ficheiros
Create file, delete file (e directórios…)
 Open, close
Read, write, reposition
Get file attributes, set file attributes
4.2.3 Gestão de dispositivos
Nota: Alguns dispositivos são tratados logicamente de uma forma análoga aos ficheiros (ex:
teclado (stdin) e ecrã (stdout)…)
Request device, release device
Read, write, reposition
Get device attributes, set device attributes
 Logically attach or detach devices
4.2.4 Manutenção de informação
Get time or date, set time or date
Get system data, set system data
Get process, file, or device attributes
Set process, file, or device attributes
4.2.5 Comunicação
Nota: A comunicação é normalmente baseada em transmissão de mensagens (conceito de
cliente e de servidor) ou partilha de memória. Nos sistemas de partilha de memória têm que
existir mecanismos de protecção e sincronização (para evitar conflitos).
Create, delete communication connection
Send, receive messages
Transfer status information
Attach or detach remote devices
4.3 Programas do Sistema
Qualquer SO contém um conjunto de programas de sistema. Nalguns casos estes programas
basicamente são interfaces para que o utilizador aceda às system calls. Noutros casos
desempenham funções bastante mais complexas.
Algumas categorias desses programas são:
Manipulação de ficheiros
Informação de estado (status)
Modificação de ficheiros (editores de texto…)
Suporte para linguagens de programação (Compiladores, linkers,…)
Carregamento e execução de programas (Debuggers, loaders, etc.)
Comunicações (login remoto, envio de mail, etc.)
_________________________________________________________________________
Eng AACucko 2023 Página 16
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
Aplicações (SGBDs, folhas de cálculo, etc.)
E ainda… o interpretador de comandos!

4.4 Estrutura do Sistema


Sendo um SO por natureza complexo é necessário bastante cuidado na forma como ele é
concebido. A abordagem mais comum em engenharia para implementar sistemas complexos é a
sua divisão em subsistemas mais simples com inputs, outputs e funções bem definidas.

4.4.1 Estrutura simples


Alguns SO actuais podem ser menos bem estruturados devido à sua história...
O DOS tem bastantes limitações pois foi construído sobre a plataforma 8088 que não possuía
dual mode e não tinha protecção de hardware. Sendo assim os programas do DOS podem
aceder directamente ao vídeo e ao disco…

As próprias versões iniciais do UNIX estavam


Programa
limitadas uma vez que o SO era constituído
apenas por duas partes:
os programas do sistema e o Kernel (núcleo). Ou Programa de sistema
seja, tudo o que estiver acima do hardware e residente
abaixo da interface system-call faz parte do kernel
( = file system, CPU scheduling, memory Drivers de
dispositivos
management, etc.).
No MS-DOS…
Drivers de
dispositivos da
ROM BIOS

Hardware…

_________________________________________________________________________
Eng AACucko 2023 Página 17
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4

4.2 Estrutura em Camadas


As novas versões do UNIX já dividem o sistema em mais módulos… (Por exemplo o AIX da
IBM)
Os desenvolvimentos ao nível do hardware permitem uma melhor modularização dos SO mais
recentes.
A estratégia de modularização mais comum é a das camadas (Layers). Aqui o SO é dividido em
camadas. Cada camada superior é construída à custa das camadas inferiores. O nível mais baixo
(0) é o nível do hardware e o nível superior é o nível da interface do utilizador.

Logon OS/2 application


Win32 application POSIX
Process
application

OS/2
POSIX
Subsytem
Subsytem
Security
Win32
Subsytem
Subsytem

User
Mode
Kernel
Mode
Executive Services

IO Manager Object Security Process Local Vituual


Manager Relerence Manager Procedure Memory
Monitor Call Facilty Manager

Kernel

Hadware Abstraction Layer (HAL)

Hadware

_________________________________________________________________________
Eng AACucko 2023 Página 18
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
Arquitectura de camadas do NT

5 Processos
Inicialmente os computadores permitiam que apenas um programa fosse executado de cada vez.
Estes programas tinham controlo total sobre a máquina e acesso a todos os recursos do
computador.
Os computadores actuais permitem que vários programas sejam carregados em memória e
executados de forma concorrente. Esta evolução dos computadores implica que exista um
controlo adequado dos vários programas. Desta necessidade resultou o aparecimento da noção
de processo que pode ser considerado como um programa em execução. Um processo é
normalmente visto como uma unidade de trabalho nos sistemas time-sharing actuais.
Um sistema pode então ser visto como um conjunto de processos que estão a ser executados:
os processos do próprio sistema operativo normalmente a correrem em modo supervisor e os
processos dos utilizadores a correrem em modo de utilizador.

5.1 Conceito de Processo


5.1.1 Processo
"Um Processo é um programa em execução". Um processo é mais do que o código do
programa. Um processo inclui geralmente uma stack, com os dados temporários (parâmetros de
subrotinas, endereços de retorno, etc) e a secção de dados que contem os dados globais do
programa.
Um programa por si só não é um processo, é uma entidade passiva (ficheiros em disco).
Um processo é uma entidade activa com um program counter que especifica a próxima
instrução a ser executada e um conjunto de recursos associados.
Podemos ter mais que um processo associado ao mesmo programa.

_________________________________________________________________________
Eng AACucko 2023 Página 19
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
5.1.2 Estado de um Processo
À medida que um processo é executado ele vai mudando de estado…
New (novo): O processo esta a ser criado
Running (a correr): As instruções do processo estão a ser executadas
Waiting (à espera): O processo está à espera que algum evento ocorra (tal como o fim de uma
operação de IO ou a recepção de um sinal)
Ready (pronto): O processo está pronto para ser atribuído a um processador
Terminated (terminado): O processo terminou a sua execução
Diagrama de estados de um processo…

Terminated
New
interrupt exit
admitt
ed

Ready Running
Scheduler dispatch
I/O or event wait
I/O or event completion

Waiting
Nota: Apenas um processo pode estar a correr num processador a cada
instante. Muitos processos podem estar ready e waiting…

5.1.3 Process Control Block


Cada processo é representado no SO pelo chamado bloco de controlo do processo (process
control block).
Algumas das informações associadas a um processo que aparecem no PCB…
Process state: O estado do processo pode ser new, ready, running, waiting, etc…
Program counter: Indica o endereço da próxima instrução do processo a ser executada
CPU registers: Os valores dos registos do processados são guardados quando ocorre uma
interrupção para permitir a continuação do processo após a interrupção…
CPU scheduling information: Esta informação inclui a prioridade associada ao processo,
ponteiros para as filas de escalonamento e outras informações necessárias ao escalonamento
Memory-management information: Pode incluir os valores dos registos base e limite
(intervalo de memória possível para o processo), tabelas de paginação, etc.…
Accounting information: Esta informação inclui tempo de CPU utilizado, tempo real utilizado,
números de conta,número de processo, etc.…
IO status information: Inclui a lista
pointer statede dispositivos de IO reservados pelo processo, lista de
ficheiros abertos, etc.…
process number

program counter
registers
memory limits
_________________________________________________________________________
Eng AACucko 2023 Página 20
list of open files

Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4

5.2 Escalonamento de Processos


O seguinte diagrama mostra como um possível sistema operativo multi-programação muda de
execução entre dois processos…

_________________________________________________________________________
Eng AACucko 2023 Página 21
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4

5.2.1 Filas de escalonamento


Usualmente quando um processo é criado é colocado numa fila de processos ou de trabalhos.
Esta fila contém todos os processos do sistema.
Os processos que estão na memória principal e que estão prontos e à espera de correr são
mantidos numa fila de programas prontos (ready queue).
Estas filas são normalmente implementadas como listas ligadas. O cabeçalho da fila conta
ponteiros para o primeiro e último PCB (program control blocks) da fila. Por sua vez cada PCB
tem um ponteiro para o próximo PCB na fila.
Existem outras filas no sistema.
Quando um processo está a correr eventualmente é interrompido, termina, fica à espera de um
determinado evento (finalização de uma operação de IO), etc. No caso de uma operação de IO
está pode ser sobre um periférico que pode ser partilhado. Neste caso o periférico pode estar a
responder a um pedido de outro processo.
É então necessária uma fila de dispositivo para conter a lista de processos que estão à espera para
utilizar um determinado dispositivo.

Quando é atribuído tempo de execução de CPU a um processo e este se encontra em execução


podem acontecer as seguintes situações:
O processo pode efectuar um pedido de IO e passar para a fila de um dispositivo
de IO
O processo pode criar um sub-processo e esperar que este termine
O processo pode ser 'removido' do CPU devido a uma interrupção de CPU (neste caso
provavelmente vai outra vez directamente para a fila de processos prontos…)
Um processo continua este ciclo de execução até terminar.
Quando um processo termina é removido de todas as filas, o seu PCB e os respectivos
recursos são libertados.

Diagrama de filas que representa o ciclo normal de escalonamento de processos

_________________________________________________________________________
Eng AACucko 2023 Página 22
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
5.2.2 Técnicas de escalonamento
Um processo ao longo da sua vida vai passando pelas diversas filas de escalonamento.
O Sistema Operativo deve seleccionar processos das filas de acordo com alguma lógica. Esta
selecção de processos é efectuada pelo método de escalonamento apropriado (scheduler).
O scheduler tem que escolher qual o processo a executar com uma frequência bastante elevada.
Normalmente o scheduler executa em cada 100 milisegundos. Como o tempo entre cada
execução do scheduler é diminuto este tem que executar muito rapidamente.
Se este demorar 10 milisegundos para escolher qual o próximo processo a executar nos
próximos 100 milisegundos então 10/(100+10)= 9% do tempo do CPU é gasto só para
escalonamento…

5.2.3 Mudança de Contexto


A mudança do processo que está a ser executado pelo CPU requer que se guarde o estado do
processo actual e que se carregue o estado do novo processo a executar pelo CPU.
Dependendo de máquina para máquina esta operação pode demorar entre 1 a 1000
microsegundos (normalmente implica a reposição do estado de todos os registos do CPU).
Alguns processadores têm instruções especiais para efectuar esta operação.
Devido ao peso que a mudança de processos pode impor a um sistema cada vez mais se estão a
utilizar novas técnicas mais leves (threads…)

5.3 Operações sobre Processos


5.3.1 Criação de Processos
Um processo pode criar novos processos durante a sua execução.
Os novos processos são designados processos filhos (children ) do processo que os criou.
Por sua vez estes novos processos podem criar outros…
podemos assim obter uma árvore de processos filhos de um processo.
Os novos processo criados desta forma vão necessitar de recursos (tempo de CPU, memória,
ficheiros, dispositivos de IO, etc.).
Os novos processos podem obter estes recursos do sistema operativo ou do processo que os
criou (pai).
Para além destes recursos normalmente o processo pai terá necessidade de passar
dados/informação para os seus processos filho…
Quando um processo cria um novo processo
Continua a executar em paralelo com o processo filho
Espera que o seu processo filho termine
Quanto ao espaço de endereçamento do novo processo criado
O processo filho é um duplicado do processo pai (fork() system call)
É carregado um programa novo para o processo filho (execve() system call)
_________________________________________________________________________
Eng AACucko 2023 Página 23
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
O system call wait() permite que o processo pai fique à espera que o processo filho termine.

5.3.2 Termino de Processos


Um processo termina quando acaba de executar a sua última instrução e pede ao sistema
operativo que o 'apague' através da system call exit().
Nessa altura o processo pode retornar dados para o processo pai. Todos os recursos do
processo dão libertados pelo sistema operativo (memória, ficheiros, periféricos, etc.).
Um processo pode também terminar através de uma chamada ao system call abort()
(normalmente chamada pelo pai do processo em questão).
Normalmente (em certos sistemas operativos - p. ex. No UNIX) quando termina um processo
todos os seus processos filho são terminados pelo sistema operativo.

5.4 Threads
Existem situações em que seria interessante a possibilidade de partilha de recursos (acesso
concorrente) entre dois processos.
Ou seja, a possibilidades de 'lançar' uma nova sequência de execução (thread) num processo
(um novo program counter…).
Grande parte dos sistemas operativos modernos suporta este mecanismo e este é designado de
thread.
Uma thread (algumas vezes designada de lightweight process - LWP) é uma unidade básica de
utilização de CPU e consiste num program counter, num conjunto de registos e numa stack.
Uma thread partilha com as outras threads do processo:
Secção de código
Secção de dados
Recursos do sistema operativo (ficheiros, etc.)
6 Gestão de processos em UNIX
 Quando o UNIX arranca apenas existe um processo visível no sistema. Este processo é
designado por init e tem o identificador (PID) 1.
 A única forma de se criar um novo processo no Unix e através da duplicação do processo
actual. Desta forma o init é o pai de todos os processos…
 Quando um processo é duplicado o processo pai e o processo filho são idênticos em
todos os aspectos à excepção dos seus PIDs (o código, dados e stack do processo filho são
iguais aos do processo pai e ambos continuam a executar o mesmo código).
 Um processo filho pode substituir o seu código pelo código de outro programa (ficheiro
executável). Desta forma o processo filho pode-se diferenciar do processo pai.
 Quando um processo filho termina a sua 'morte' é comunicada ao processo pai.
Exemplo (processamento de um utilitário pela shell do Unix):

_________________________________________________________________________
Eng AACucko 2023 Página 24
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4

6.1 Criação de um novo processo (fork)


A instrução fork permite duplicar um processo.
O processo filho criado é praticamente uma cópia do processo pai. O processo filho herda uma
cópia do código, dados, stack, ficheiros abertos, etc., do processo pai.
Apesar disso o filho e o pai têm identificadores de processo diferentes.
Se o fork for bem sucedido ele retorna o identificador de processo filho criado ao processo pai
e retorna 0 ao processo filho. Se o fork falhar retorna -1 para o processo pai e o processo filho
não é criado.
Nota: No caso do processo pai terminar primeiro que o filho o sistema adopta o processo filho
através do processo PID 1.
6.2 Obter a identificação de um processo (getpid, getppid)
A função getpid() retorna o identificador do processo actual.
A função getppid() retorna o identificador do processo pai do processo actual.
Ambas as funções retornam sempre com sucesso.

6.3 Terminar um processo (exit)


O exit termina o processo actual, libertando todos os seus recursos (descri tores de ficheiros,
código do processo, dados do processo, stack, etc.). O parâmetro passado para o exit é
enviado ao processo pai (este parâmetro é normalmente designado de status).
Quando um processo filho termina, é enviado um sinal SIGCHLD para o pai do processo. O
processo filho fica à espera que o pai aceite o sinal enviado (ou seja, que o pai aceite o código
de retorno - status). Um processo neste estado é designado de processo zombie.
A forma que o processo pai tem para aceitar o status do processo filho é a instrução wait.
Um processo filho só é libertado do sistema após o pai ter aceite o seu código de status (via a
instrução wait).
Se o pai 'morrer' primeiro que o filho o processo filho é automaticamente 'adoptado' pelo
processo init. O processo init aceita sempre o código de status de um processo filho.
_________________________________________________________________________
Eng AACucko 2023 Página 25
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
A instrução exit nunca retorna…

6.4 Esperar por um processo filho (wait)


A instrução wait faz com que o processo fique suspenso até que um dos seus processos filhos
termine.
A instrução wait retorna o identificador (PID) do processo filho que terminou e retorna também
o código de termino do processo filho como parâmetro.
A codificação desse parâmetro (um inteiro de 16 bits) é a seguinte:
 Se o byte mais à direita é zero então o byte da esquerda contem os oito bits menos
significativos do valor retornado pela instrução exit do processo filho.
 Se o byte mais à direita é diferente de zero, então os sete bits mais à direita representam o
sinal que fez com que o processo filho terminasse e o oitavo bit é 1 se o processo filho produziu
um core dump.
Se o processo que executa o wait não tem filhos então o wait retorna imediatamente -1.
Se o processo que executa o wait tem vários processos filhos que são zombies então o wait
retorna imediatamente com o status de um desses zombies.

6.5 Criação de um novo processo/programa (exec)


Um processo pode substituir o seu código, dados e stack pelos valores de outro executável
através da instrução exec.
Quando um processo utiliza a função exec o seu PID e PPID permanecem iguais (apenas é
alterado o código que o processo está a executar).
Existem várias versões da instrução exec cujo objectivo é permitirem várias formas de passagem
de parâmetros.
O exec aceita como parâmetros o nome (path) do programa que deve ser carregado assim como
eventuais parâmetros para o programa.
Se o exec falhar (p. ex. o executável não existe) retorna -1. Caso o executável exista o seu
código, dados e stack são carregados e o seu código é executado.

7 Gestão de processos em NT
 Um processo é um programa que esta carregado em memória e preparado para execução.
 Cada processo tem um espaço de endereçamento virtual privado.
 Um processo consiste em código, dados e outros recursos de sistema (tais como
ficheiros…) que estão acessíveis às threads do processo.
 Uma thread é uma unidade de execução de um processo.
 Cada thread de um processo está associada a uma sequência de instruções de CPU, um
conjunto de registos de CPU e a uma stack.
 Um processo não executa código.
 Um processo é apenas o espaço de endereçamento onde se encontra o código.

_________________________________________________________________________
Eng AACucko 2023 Página 26
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
O código contido no espaço de endereçamento de um processo
é executado por threads.
 Cada processo arranca com uma única thread, mas pode criar outras threads (independentes
umas das outras) para executarem parte do seu código
Forma de atribuição de tempo de CPU às Threads no NT
Thread Thread

Thread Thread

Thread Thread

Thread
Thread

Thread Thread

_________________________________________________________________________
Eng AACucko 2023 Página 27
UDM Tema: Introdução aos Sistemas Operativos

7.1 Criação de Processos


 A criação de um novo processo no NT é feita através da função CreateProcess.
 Esta função cria um novo processo que corre independentemente do processo que o
criou. Apesar disso é usual manter-se a utilização dos termos 'processo pai' e 'processo
filho'.
 Se a função executa com sucesso retorna na estrutura PROCESS_INFORMATION
informação sobre o novo processo criado e sobre a sua thread principal (nomeadamente os
handles do novo processo e da sua thread principal).
 A função CreateProcessAsUser permite que se especifique em que contexto de
segurança é que vai correr o novo processo (na 'conta' de um determinado utilizador…)

7.2 Informação sobre processos


 Quando um processo é criado pelo CreateProcess a função retorna os handles do novo
processo assim como da sua thread principal. Estes handles podem ser
utilizados em qualquer função que necessita de handles de
processos ou de threads.
 O CreateProcess também retorna o identificador do novo processo e da thread principal.
Estes identificadores são únicos e globais ao sistema.
 Um processo pode ir buscar o seu identificador através da função GetCurrentProcessId.
 A função OpenProcess permite obter um handle dum processo dado o seu identificador.
 A função GetCurrentProcess permite que se obtenha um pseudo-handle para o processo
actual. É um pseudo-handle pois só pode ser usado no processo actual; não pode ser
herdado ou duplicado para utilização noutros processos.
 A função DuplicateHandle permite obter o handle 'real' do processo dado o pesudo-
handle.
Outras funções
 GetCommandLine permite obter a linha de comando para o processo actual
 GetModuleFileName permite obter o caminho e nome do ficheiro executável que
contem o código do processo actual.
 GetProcessTimes permite obter informação sobre o tempo de execução de um
processo: tempo de criação; quanto tempo executou em modo kernel; quanto tempo
executou em modo utilizador.

7.3 Herança
 Um processo filho pode herdar várias propriedades e recursos do processo pai.
 Pode-se 'evitar' que um processo filho herde determinada informação do processo pai.
Informação que pode ser herdade pelo processo filho:
 Handles abertos, como os handles de ficheiros (CreateFile…)

Ficha1- 1 a 5 Sistemas Operativos pagina 28


UDM Tema: Introdução aos Sistemas Operativos

 Handles abertos de processos, threads, etc.


 Variáveis de ambiente
 Directório actual…

7.3.1 Herança de Handles


Para que um handle possa ser herdado:
 Deve-se especificar que o handle é para ser herdado quando se cria, abre ou duplica o
handle
 No CreateProcess deve-se especificar que desejamos que os handles devem ser
herdados.
 Desta forma podemos herdar só alguns handles.
Nota: os handles herdados referem o mesmo objecto no processo pai e no processo filho.

7.3.2 Herança de variáveis de ambiente


 Por defeito um processo herda as variáveis de ambiente do processo pai.
 O CreateProcess permite que se indique um bloco diferente de variáveis de ambiente.
 A função GetEnvironmentStrings retorna as variáveis de ambiente do processo actual
(read-only). Este bloco de variáveis deve ser libertado por FreeEnvironmentStrings.
 A função SetEnvironmentVariable permite alterar o
valor de uma variável de ambiente do processo actual. A função GetEnvironmentVariable
faz o inverso.

7.4 Termino de processos


Um processo executa até acontecer uma das seguintes situações:
 Uma thread do processo executa a função ExitProcess. Esta função termina todas as
threads de um processo.
 A thread principal do programa termina. Para que a thread principal de um processo possa
terminar sem terminar as outras threads do processo ela deve chamar a função ExitThread.
Termina a última thread do processo.
Qualquer thread do processo executa a função TerminateProcess passando o handle do
processo. Esta função termina todas as threads de um processo não permitindo que estas
executem rotinas de saída (guardar dados, libertar memória, etc.).
A função GetExitCodeProcess permite saber qual o código de retorno de um processo
(valor passado em ExitProcess ou TerminateProcess)
Nota: Quando um processo termina o sistema operativo não termina os seus processos filho.

7.5 Threads
7.5.1 Criação de threads

Ficha1- 1 a 5 Sistemas Operativos pagina 29


UDM Tema: Introdução aos Sistemas Operativos

 A função CreateThread cria uma nova thread no processo actual.


 Deve-se especificar o endereço inicial do código que será executado pela nova thread.
 Normalmente o endereço inicial é o nome de uma função definida no código do
programa. Esta função deve ter um único parâmetro e retornar um
DWORD.
 Um processo pode ter múltiplas threads a executar a mesma função.

7.5.2 Informação sobre threads


 A função CreateThread retorna um handle para a thread que pode ser utilizado em todas
as funções que necessitam de um handle de uma thread.
 A função CreateThread também retorna o identificador universal da thread no sistema.
 A função GetCurrentThreadId permite obter o identificador da thread actual.
 A função GetCurrentThread retorna um pseudo-handle.
 A função DuplicateHandle permite
obter o handle real da thread dado o seu psedo-handle.
 GetThreadTimes permite obter informação sobre o tempo de execução de uma thread:
tempo de criação; quanto tempo executou em modo
kernel; quanto tempo executou em modo utilizador.

7.5.3 Estado de execução de uma thread


 A função SuspendThread permite suspender a execução de uma thread. Enquanto a
thread está suspensa esta não é escalonada para tempo de processador.
 A função ResumeThread permite que uma thread deixe o estado de suspensa.
 A função Sleep permite suspender a execução de uma thread por um determinado
intervalo de tempo.
 A função SwitchToThread permite que uma thread ceda o seu tempo de execução de
processador actual a outra thread que esteja pronta para execução.

7.5.4 Termino de uma thread


 ExitThread, ExitProcess, TerminateThread, TerminateProcess
 GetExitCodeThread permite obter o código de retorno passado pelas funções anteriores
ou retornado pela função da thread.

Ficha1- 1 a 5 Sistemas Operativos pagina 30


UDM Tema: Introdução aos Sistemas Operativos

8 Gestão de processos em OS/400


8.1 Noções sobre Processos no AS/400
O Sistema AS/400 baseia-se num conceito designado por Machine Interface (MI).
Podemos afirmar que o MI encaixa no conceito de MicroKernel.
Podemos ver o MI como um conjunto de funções que representam uma máquina virtual.
Essa máquina virtual conhece o detalhe do hardware sobre o qual esta a correr e esconde
esses detalhes das camadas superiores.
O OS/400 (sistema operativo que corre na arquitectura AS/400) corre sobre o MI.
Assim, o hardware e as partes do SO que têm que conhecer os detalhes do hardware correm
abaixo do MI.
Os AS/400 são normalmente equipados com processadores RISC PowerPC (64bits).
Uma das características que mais se salienta no AS/400 para além do MI é o seu conceito de
Single Level Store, ou seja, um único nível de armazenamento. O AS/400 não faz distinção
entre memória principal e memória secundária. Os ponteiros no AS/400 têm 16 bytes de
comprimento!
Programas

OS/400
MI

LIC (Licensed Internal


Code)
Hardware
Note-se que ao nível do MI os operandos das instruções são objectos ao contrário do nível
do hardware em que os operandos são normalmente registos, posições de memória ou
constantes.
O software do sistema operativo que se encontra abaixo do MI é designado de Licensed
Internal Code (LIC).
O OS/400 consiste num conjunto de programas e objectos que correm em cima do MI.
O LIC consiste em estruturas de dados e programas que se encontram entre o MI e o
hardware.
O Sistema Operativo do AS/400 é a combinação do OS/400 e do LIC. Note-se, no entanto,
que algum código do MI pode ser 'traduzido' directamente para instruções do hardware

Ficha1- 1 a 5 Sistemas Operativos pagina 31


UDM Tema: Introdução aos Sistemas Operativos

(PowerPC) e neste caso não utiliza os serviços do LIC.


Alguns conceitos sobre a Gestão de Processos no AS/400
As aplicações e os componentes do sistema operativo no AS/400 comunicam através de
mensagens.
Um processo no AS/400 é uma funcionalidade de alto-nível no LIC que é suportada em cima
de outro conceito: a tarefa (task).
Em termos de AS/400 ainda existe outro conceito de mais alto nível que é o de trabalho
(job).
Cada task tem um Control Block designado Task Dispatching Element (TDE) que apenas é
visível abaixo do nível do MI.
O comando WRKSYSSTS do AS/400 permite ver as tarefas existentes no sistema e os
respectivos estados (ready, wait, etc.).
O TDQ - Task Dispatching Queue - é a fila que contém todas as tarefas prontas para terem
tempo de CPU ordenadas por prioridade. No AS/400 uma tarefa em execução pode ser
interrompida e substituída por uma tarefa de prioridade mais elevada.
Para sincronização entre tarefas o AS/400 utiliza mecanismos de mensagens (podemos afirmar
que cada tarefa tem a sua 'mailbox'…).
Note-se que a partir de 1990 é que a IBM começa a lançar AS/400 que suportam múltiplos
processadores.
No caso de sistemas multiprocessados o usual é continuar a existir apenas uma TDQ
embora à medida que o número de processadores aumenta a utilização de apenas uma TDQ
pode ser um ponto de estrangulamento. Nestes casos podem-se utilizar múltiplas TDQs.
Neste sistemas multiprocessados as tarefas passam a ter uma propriedade que é designada
por 'cache affinity'. Este conceito consiste em atribuir a uma tarefa uma determinada
afinidade para um determinado processador baseada no conteúdo da cache desse
processador.
O Conceito de Processo no AS/400
Um processo é um objecto do sistema ao nível do MI.
Esse objecto é designado por Process Control Space.
Não existe nenhum conceito equivalente acima do nível do MI.
A principal responsabilidade de um processo do MI é a de agrupar numa unidade lógica
todos os recursos necessários para executar um programa.
O modelo de processos original do AS/400 foi desenhado para suportar
linguagens como o RPG o COBOL e o CL. O modelo original reflectia a estrutura deste tipo
de linguagens na qual cada processo é uma unidade de trabalho e os programas executados
pelo processo são por principio pouco modulares.
Este modelo (utilizado nas primeiras versões do AS/400) era bastante eficiente no contexto
das referidas linguagens. A recente evolução para linguagens estruturadas no conceito de
bloco e a estratégia no sentido de suportar standards (tal como o POSIX) levaram ao
desenvolvimento de novo modelo de processos designado por ILE Process Model.
O Modelo de Processos ILE

Ficha1- 1 a 5 Sistemas Operativos pagina 32


UDM Tema: Introdução aos Sistemas Operativos

Este novo modelo assenta nos seguintes conceitos: Módulos: têm um ou mais procedimentos

Programas: têm vários módulos


Programas de Serviços: têm vários módulos
Neste modelo o comando CALLPGM permite invocar programas e o comando CALLBP
permite invocar procedimentos.
Para suportar esta nova estrutura o principal conceito introduzido foi o de Grupo de
Activação (Activation Group).
O Grupo de Activação 'fornece' todo o espaço de armazenamento que um ou mais
programas necessitam:
- Static Storage Area (global ao Activation Group) - Automatic Storage Area (Stack)
- Heap Storage Area (este conceito não existia no modelo inicial)
O Activation Group é criado para nele serem executados um ou mais programas.
Um activation Group não é um objecto de sistema ao nível do MI. Um activation Group
pertence (faz parte) de um processo do MI. Cada Processo do MI contém dois ou mais
Activation Groups. Um desses Activation Groups é utilizado pelo sistema.
Assim a estrutura de um Processo ILE passa a ser constituída pelos seguintes componentes
principais:
-PCB: contém o TDE (Task Dispatching Element) para oprocesso
- PAWA: Process Activation Work Area (é uma heap) - PAGP: Parent Activation Group
-ACTGRP: Activation Group - Etc.
Cada Activation Group (ACTGRP) contém um PACB (Program Activation Control Block)
por cada programa activado assim como o seu vector de 'bindings' para módulos 'linkados'.
O Conceito de Trabalho (Job) no AS/400
Do ponto de vista do utilizador o AS/400 apresenta o conceito de Job que se aproxima mais
das noções utilizadas em aplicações de negócio.
O conceito de Job é construído à custa do conceito de processo do MI. Um Job é uma
unidade de execução submetida ao sistema pelo utilizador.
Um processo de MI não tem nenhum objecto semelhante em termos de OS/400.
Um Job não é um objecto do OS/400. O Gestor de Trabalhos do AS/400 lida directamente
com os processos.
Um Job pode ser executado num único processo ou pode ser executado num conjunto de
processos cuja iniciação é gerida por um conjunto de processos de controlo. Do ponto de
vista do utilizador cada iniciação de um novo processo no âmbito de um Job é designada
por Routing Step.
Assim podemos considerar a seguinte hierarquia de conceitos:
SYSTEM
SUB-SYSTEM (executa tipos de Jobs semelhantes)
JOB
ROUTING STEP ( equivale a um processo no MI)

Ficha1- 1 a 5 Sistemas Operativos pagina 33


UDM Tema: Introdução aos Sistemas Operativos

(processo equivale a uma tarefa no LIC)

O suporte de Threads no AS/400


Na implementação actual uma Thread é um Job do AS/400 que partilha um Activation
Group.
Assim, um Processo POSIX pode ser visto como todos os Jobs do AS/400 que partilham
um Activation Group.
Como o Job é um conceito um pouco 'pesado' comparativamente à Thread na
implementação actual o AS/400 mantém uma 'pool' de Jobs pré-criados de forma a que eles
possam ser utilizados quando necessário sem o peso da sua criação.

8.2 Threads no OS/400


 Actualmente o OS/400 suporta um conjunto de API (Application Programming
Interface) que é baseado na especificação X/Open e no POSIX (Portable Operating System
Interface).
 Esta API é designada por CPA: Common Programming APIs Toolkit/400.
 Grande parte do conjunto de funções desta API suporta o conceito de
thread do OS/400.
 O Modelo de programação baseado em threads é óptimo para ambientes tipo
cliente/servidor.
 É usual implementar-se servidores como threads 'especiais' que estão à espera de
pedidos de clientes e que criam uma nova thread para processar
e responder a cada um desses pedidos.
 Outra das utilizações das threads são as de permitir que um programa continue o
seu processamento enquanto outra parte do programa está à espera de algum recurso ou
evento.
 A implementação de threads pelo CPA é baseada no conceito de trabalhos (jobs) do
OS/400.
 As threads do CPA são trabalhos de OS/400 que partilham a mesma zona de
armazenamento, ou seja, em termos de trabalhos de OS/400 pertencem ao mesmo grupo de
activação (activation group).
 Assim todos os trabalhos de OS/400 que partilham o mesmo grupo de activação
constituem um processo.
 Todas as threads do mesmo processo partilham o mesmo armazenamento global
estático e de heap. Cada thread tém a sua própria stack e área de armazenamento automática.

8.3 Criação de Threads


 Quando um programa CPA é criado o sistema cria e inicializa estruturas de controlo que
vão permitir que o processo seja multithreaded .
 O trabalho (job) no qual o programa é chamado torna-se a thread inicial, ou primária, do
processo multithreaded.

Ficha1- 1 a 5 Sistemas Operativos pagina 34


UDM Tema: Introdução aos Sistemas Operativos

 A thread inicial é especial. Esta deve permanecer activa durante a duração da aplicação. Se
ela termina por alguma razão então todas as threads secundárias são terminadas antes da
thread inicial terminar.
 As threads secundárias são criadas através da função pthread_create(). Esta função cria
um novo trabalho que começa a executar a função especificada pelo utilizador. O trabalho é
criado internamente por um interface de sistema que permite a criação de trabalhos de forma
rápida…
 Este novo trabalho tém a mesma lista de bibliotecas (…directórios…), perfil de utilizador
e atributos de execução do trabalho da thread inicial.
 A função pthread_create retorna o identificador da nova thread (thread id). Este número
é derivado do número do trabalho (job id).
 A CPA tenta sempre criar as threads secundárias de uma pool de trabalhos em standby.
Esta pool contém trabalhos de OS/400 já utilizados para threads secundárias do mesmo
processo. Esta é uma forma de acelerar a criação de threads.
 Na chamada a ptherad_create pode-se passar um parâmetro para a thread secundária que
está a ser criada.

8.4 Esperar que uma Thread termine


 Uma thead pode esperar que outra thread termine através da função pthread_join.
Como parâmetro para esta função deve passar-se o identificador da thread pela qual
queremos esperar.
 A função pthread_join pode retornar o valor de retorno da thread que termina.

8.5 Terminar uma Thread


 Existem várias formas para terminar uma thread no CPA:
 A função pthread_exit() termina a thread de forma normal e permite que se passe
o valor de retorno para a função pthread_join.
Neste caso o trabalho associado a thread entra normalmente para a pool de trabalhos do
processo.
 O CPA chama automaticamente a função pthread_exit() se a thread chega ao fim da sua
função.
 Uma thread pode terminar explicitamente outra thread através da função
pthread_cancel().
 O utilizador do OS/400 pode parar a thread se terminarem interactivamente o trabalho que
a esta a executar. Neste caso também terminam todas as outras threads do processo.
 As funções exit() e abort() também terminam a thread assim como todas as outras threads
do processo.
 Se terminar por qualquer forma a thread inicial então todas as outras threads também
terminam.

8.6 Utilização do CPA


 No inicio do programa deve-se incluir <pthread.h>.

Ficha1- 1 a 5 Sistemas Operativos pagina 35


UDM Tema: Introdução aos Sistemas Operativos

 A função inicial do programa deve ser: int user_main(int


argc, char* argv[])
Para facilitar o header file <pthread.h> redefine main() em user_main() para que se possam
escrever programas 'normais' com a função main().

9 Escalonamento de CPU
O escalonamento de CPU é a base dos sistemas operativos multiprogramação. Partilhando
a execução do CPU por vários processos o sistema operativo torna o computador mais
produtivo
9.1 Conceitos básicos
 O objectivo da multiprogramação é ter sempre um processo a executar, de forma a
maximizar a utilização do CPU.
 Para sistemas com um único processador nunca existirá mais do que um processo a
executar. Se existirem mais processos estes terão de esperar até
que o CPU fique livre e que o sistema operativo determine qual o próximo processo a ter
tempo de CPU.
 O conceito de multiprogramação é bastante simples. Um processo é executado até ter que
esperar (normalmente ter que esperar pela execução de uma operação de IO). Num sistema
operativo básico o CPU ficaria parado sem fazer absolutamente nada. Num sistema com
multiprogramação vários processos estão em memória ao mesmo tempo. Quando um
processo fica à espera de alguma operação o SO utiliza o tempo de CPU para executar outro
processo que esteja em memória. Este é o principio básico do escalonamento de
processos.
 Note-se que quase todos os recursos de um computador têm que ser escalonados (não
só o processador…).
9.2 Ciclo CPU-IO

Ficha1- 1 a 5 Sistemas Operativos pagina 36


UDM Tema: Introdução aos Sistemas Operativos

 Podemos considerar que o ciclo de execução de um


processo consiste em ciclo de execução de CPU e ciclo
de execução de IO.
 Os processos vão alternando entre estes dois estados.
 A execução de um processo começa pela execução de
uma sequência de CPU (CPU burst). Esta sequência é
seguida por uma de IO que é seguida por uma de CPU e
assim sucessivamente. Finalmente alguma sequência de
CPU deve executar um pedido de termino de processo…
 A experiência mostra que na maior parte dos casos
existe um grande número de sequências de CPU de
pequena duração e um pequeno número de sequências de
CPU de grande duração.
 Um processo com bastante IO normalmente terá muitas
pequenas sequências de CPU…

Exemplo da alternância entre sequências de CPU e IO

 Um processo de CPU normalmente terá algumas sequências de CPU de grande duração.


 Estas considerações são bastante importantes na escolha do melhor algoritmo de
escalonamento de CPU.

9.3 Escalonamento de CPU


 Sempre que o CPU se encontra parado (idle) o sistema operativo tem que escolher um
dos processos que se encontra na fila de processo prontos (ready) para ser executado.
 Este processo de selecção é executado pelo módulo/algoritmo de escalonamento de
CPU.
 O Algoritmo selecciona um dos processos que se encontra na fila de processos prontos e
atribui a execução do CPU a esse processo.
 Note-se que a fila de processos prontos para execução não é necessariamente uma fila
do tipo FIFO (First In First Out).
 A informação que se encontra nessa fila é normalmente constituída pelos PCBs dos
processos.
9.3.1 Escalonamento do tipo Preemptive
 As decisões de escalonamento são efectuadas nas seguintes situações:
 Quando um processo muda do estado de execução para o estado de espera (por
exemplo, pela execução de uma instrução de IO ou pela invocação de um wait sobre o
termino de um dos seus processos filhos).

Ficha1- 1 a 5 Sistemas Operativos pagina 37


UDM Tema: Introdução aos Sistemas Operativos

 Quando um processo muda do estado de execução para o estado de pronto (por


exemplo quando ocorre uma interrupção).
 Quando um processo muda do estado de espera para o estado de pronto (por exemplo
por o pedido de IO se ter completado).
 Quando um processo termina
 Para o primeiro e último caso não existe escolha possível em termos de escalonamento.
Tem de ser seleccionado um novo processo que esteja pronto para ser executado
(escalonamento não preemptive).
 Na segunda e terceira situação já existe possibilidade de escolha em termos de
escalonamento (escalonamento preemptive).
 Escalonamento não preemptive: Neste caso assim que o CPU é atribuído a um
processo o processo mantém-se na utilização do CPU até libertar a sua utilização por ter
terminado ou por mudar para o estado de espera (Ex: Windows 3.X).
 Escalonamento preemptive: Neste caso o SO mantém controlo sobre o tempo máximo
de execução de CPU consecutiva que um processo pode ter.
Nesta situação surgem novas considerações como, por exemplo, o que acontece se um
processo é interrompido a meio de uma escrita para uma zona de dados partilhada?…

9.3.2 Despacho (Dispatcher)


O módulo de despacho é aquele que atribui a execução do CPU ao processo seleccionado
pelo algoritmo de escalonamento. Envolve:
 Mudança de contexto
 Mudança para modo de utilizador
 Salto para o local adequado do programa para que este possa continuar a
partir da sua última instrução executada.
 Este módulo deve ser o mais rápido possível uma vez que tem que ser invocado sempre
que o CPU muda de processo.
 O tempo que demora o dispatcher a parar um processo e arrancar outro é designado de
dispatch latency.

9.4 Critérios de escalonamento


 Existem diversos algoritmos de escalonamento com características
diferentes/propriedades que podem favorecer diferentes tipos de processos.
 Para se determinar qual o melhor algoritmo para uma determinada situação é necessário
ter em conta estas características.
 Os critérios para comparação de algoritmos normalmente incluem:
 CPU utilization: O objectivo é manter o CPU no máximo possível da sua ocupação. Em

Ficha1- 1 a 5 Sistemas Operativos pagina 38


UDM Tema: Introdução aos Sistemas Operativos

situações normais esse tempo de ocupação pode variar entre 40% e 90%. (Maximizar)
 Throughput: Se o CPU estiver ocupado então ele esta a executar trabalho. Um método
possível para contabilizar esses trabalho é o número de processos terminados por unidade
de tempo… (Maximizar)
 Turnaround time: Do ponto de vista de um processo em particular o que interessa é
quanto tempo demora a executar esse processo. Este é o intervalo desde a submissão do
processo até à sua conclusão. Assim o turnaround time é a soma dos tempos em que ele
esteve a executar, à espera da fila de IO, a ser carregado
em Processo Burst Time memória, à espera da fila de processos prontos,
etc. P1 24 (Minimizar)
P2 3
 Waiting P3 3
time: O algoritmo de escalonamento de CPU
não afecta o tempo que um processo passa em
execução ou a efectuar IO; afecta apenas o tempo que o processo passa à espera na fila de
processos prontos para execução. O waiting time é a soma de todos os períodos que o
processo passou na fila de processos prontos. (Minimizar)
 Response time: Nos sistemas interactivos o turnaround pode não ser o melhor critério.
Normalmente um processo pode começar a obter resultados logo no inicio e continuar a
processar novos resultados… (Minimizar)
Assim, uma medida importante é o tempo que demora um processo a começar a obter
resultados desde a sua submissão.

9.5 Algoritmos de escalonamento


Os algoritmos de escalonamento de CPU devem decidir qual dos processos que esta na fila
de processos prontos deve ser atribuído ao CPU.

9.5.1 First-Come, First-Served


Este é talvez o algoritmo mais simples.
 Neste algoritmo o processo que requer o CPU primeiro é atendido
primeiro.
 A implementação/gestão dos processos é feita através de uma fila FIFO.
 O tempo médio de espera de um processo neste caso pode ser elevado.
Exemplo:

Se os processos chegarem na ordem P1, P2, P3 obtemos o seguinte resultado:


Tempos de espera: P1(0), P2(24) e P3(27)
Tempo Médio de Espera: (0 + 24 + 27)/3=17
Se os processos chegarem na ordem P2, P3, P1 obtemos o seguinte resultado:
P2 P3 P1
0 3 6 30
Tempos de espera: P1(6), P2(0) e P3(3)

Ficha1- 1 a 5 Sistemas Operativos pagina 39


UDM Tema: Introdução aos Sistemas Operativos

Tempo Médio de Espera: (6 + 0 + 3)/3=3

9.5.2 Shortest-Job-First
 Neste algoritmo cada processo tem associado o tamanho do seu próximo CPU burst (ou
seja, quanto tempo de CPU é que o
processo vai ocupar a seguir).
 Quando o CPU fica disponível é atribuído ao processo que tiver o menor
CPU burst. No caso desse tempo ser igual para dois ou mais processos é utilizado o
algoritmo FCFS.
Exemplo:

Processo Burst Time


P1 5
P2 8
P1 P2 P3
0 24 27 30
P3 7
P4 3

Utilizando este algoritmo obteríamos o seguinte resultado:

P4 P1 P3 P2
0 3 9 16 24
Tempos de espera: P1(3), P2(16), P3(9) e P4(0)
Tempo Médio de Espera: (3 + 16 + 9 + 0)/4=7
(Note-se que em FCFS seria igual a 10.25)
Note-se que este algoritmo é quase óptimo pois:
 Permite que se obtenha um tempo médio mínimo de espera para um
determinado conjunto de processos
 Movendo um processo de duração curta para a frente de um processo de
duração maior o tempo de espera do processo pequeno
diminui mais que o aumento no tempo de espera do processo mais longo… Assim o tempo
médio de espera diminui.
 O problema com este algoritmo é o de ser muito difícil, senão impossível,
conhecer a duração da próxima utilização de CPU de
um processo (CPU burst).
 Uma aproximação é tentar utilizar os tempos anteriores de utilização de CPU de
um processo para prever o próximo…

9..3 Priority
 O algoritmo anterior é um caso particular de um algoritmo mais genérico de
escalonamento utilizando prioridade.
 Neste caso uma prioridade é associada a cada processo e o CPU é atribuído ao processo
com maior prioridade.
Processos com a mesma prioridade são servidos com uma ordem do tipo FCFS.

Ficha1- 1 a 5 Sistemas Operativos pagina 40


UDM Tema: Introdução aos Sistemas Operativos

 O algoritmo anterior é um algoritmo de prioridade no qual o valor dessa prioridade pode


ser calculado como o inverso do tempo de duração da próxima utilização de CPU.
 Note-se que nalguns SO as prioridades mais elevadas são representadas pelos números
maiores e noutros passa-se o contrário. Nos
exemplos a seguir a maior prioridade corresponde ao número menor.
Exemplo:

Processo Burst Time Priority


P1 10 3
P2 1 1
P3 2 3
P4 1 4
P5 5 2

Utilizando este algoritmo obteríamos o seguinte resultado:

P2 P5 P1 P3 P4
0 1 6 16 18 19

Tempos de espera: P1(6), P2(0), P3(16), P4(18) e P5(1)


Tempo Médio de Espera: (6 + 0 + 16 + 18 + 1)/5=8.2
 As Prioridades podem ser definidas internamente ou externamente ao SO.
 Internamente o SO pode utilizar diversos valores quantificáveis para calcular a prioridade:
número de ficheiros abertos, necessidades em termos de memória, comparação entre a
média de tempo de IO e de CPU, etc.
 As prioridades externas são atribuídas normalmente pelo utilizador e podem ser baseadas
em qualquer tipo de raciocínio ou política.
 Um grande problema com este tipo de algoritmos de escalonamento é o facto de
eventualmente acontecer que um processo de
prioridade baixa nunca seja executado!
 Esta situação é normalmente resolvida através do incremento periódico
da prioridade dos processos mais antigos (com mais idade no sistema).

9.5.4 Round-Robin
Este algoritmo é semelhante ao FCFS e é utilizado em particular nos sistemas do tipo time-
sharing ou interactivos.
 Neste caso é definido um intervalo de tempo (time quantum ou time slice) (geralmente
entre os 10 e os 100milisegundos).
 A fila de processos passa a ser uma fila circular.
 O algoritmo de escalonamento percorre a lista circular de processos prontos atribuindo
tempo de CPU a cada processo no máximo durante um quantum ou time slice.
 Se o tempo de CPU de um processo (burst time) for superior ao time slice
este é interrompido (preemptive scheduling) e volta para a cauda da lista de processos
prontos.

Ficha1- 1 a 5 Sistemas Operativos pagina 41


UDM Tema: Introdução aos Sistemas Operativos

 Sempre que o algoritmo de escalonamento despacha um processo para o CPU


activa o temporizador de interrupção para um time slice.
Exemplo:

Processo Burst Time


P1 24
P2 3
P3 3

Utilizando este algoritmo obteríamos o seguinte resultado:


P1 P2 P3 P1 P1 P1 P1 P1
0 4 7 10 14 18 22 26 28

Tempo Médio de Espera: ((0+(10-4)) + 4 + 7)/3 = 5.66


Nota: Num cenário ideal os time burst dos processos deveriam ser iguais ao time slice
(diminuindo o peso da mudança de contexto entre processos…)

10 Escalonamento de CPU (cont.)


10.1 Escalonamento "Multilevel Queue"
 Este é um tipo de algoritmo de escalonamento para situações nas quais os processos
podem ser facilmente classificados em diferentes grupos.
 Um exemplo é a divisão possível de se fazer entre processos interactivos (foreground) e
processos lote/batch (background).
Estes dois tipos de processos têm necessidades de tempos de resposta diferentes e assim
diferentes necessidades em termos de escalonamento.
 Um algoritmo "multilevel queue" divide a fila de processos prontos em diferentes filas
separadas.
 Os processos são atribuídos a uma fila em função de alguma propriedade do processo
como o espaço de memória, a prioridade ou o tipo de processo.
 Cada fila pode ter o seu algoritmo de escalonamento. Por exemplo a fila de processos
foreground pode usar RR (roundrobin) e a de background FCFS.

Ficha1- 1 a 5 Sistemas Operativos pagina 42


UDM Tema: Introdução aos Sistemas Operativos

 Além disso existe também o escalonamento entre filas que normalmente é do tipo
prioridade fixa, ou seja, a fila de foreground tem prioridade sobre a de background (para um
processo background executar é necessário que a fila de foreground esteja vazia…).
 Outra hipótese é a de estabelecer também um time-slice entre filas (Ex: 80% para fila de
foreground e 20% para fila de background).
Prioridade mais elevada

Processos do sistema

Processos interactivos

Processos em lote
Prioridade mais baixa
10.2 Escalonamento "Multilevel Feedback Queue"
Normalmente no algoritmo de escalonamento "Multilevel Queue" os processos são
atribuídos às respectivas filas e permanecem nelas até terminarem.
O facto de não permitir que os processos mudem de fila torna o algoritmo mais
simples e mais leve mas também pouco flexível.
O algoritmo "Multilevel Feedback Queue" permite que os processos mudem de fila. A
ideia é separar os processos com necessidades de processamento de CPU diferentes.
Se um processo utiliza demasiado tempo de CPU então é transferido para uma fila de
menor prioridade. Este esquema permite deixar os processos de muito IO ou interactivos nas
filas de maior prioridade.
De forma semelhante um processo que fique durante muito tempo numa fila de baixa
prioridade pode ser promovido para uma fila de mais alta prioridade (de forma a que este não
fique à espera para sempre…).
Ex:
Um processo entra no sistema e vai para a fila 0 (maior prioridade). Um processo nesta
fila tem um time-slice de 8 milisegundos.
Se o processo não terminar nesse time-slice é movido para o fim da fila 1.
Se a fila 0 estiver vazia ao primeiro processo da fila 1 é atribuído um time-slice de 16
milisegundos.
Se o processo não terminar nesse time-slice então é movido para a fila 2.
Os processos na fila 2 são executados por uma estratégia de FCFS e só quando as filas 0
e 1 estão vazias.
Os algoritmos deste tipo são os algoritmos de escalonamento de CPU mais genéricos.
Estes algoritmos são também os mais complexos.

10.3 Escalonamento em sistemas multiprocessados

Ficha1- 1 a 5 Sistemas Operativos pagina 43


UDM Tema: Introdução aos Sistemas Operativos

Quando um sistema é constituído por múltiplos processadores o problema do


escalonamento torna-se mais complexo.
Nesta situação, tal como nas anteriores, não existe nenhuma situação real óptima.
Algumas considerações sobre este tipo de sistemas…
Normalmente os processadores são idênticos (homogéneos) relativamente à sua
funcionalidade, ou seja, qualquer processador disponível pode ser utilizado para executar
qualquer processo que esteja na fila de processos prontos.
Se os processadores forem diferentes apenas podem executar processos compilados para
executarem no respectivo processador (…normalmente é o caso dos sistemas
distribuídos…).
Mesmo em sistemas homogéneos podem existir problemas de escalonamento (Ex: Um
dos processadores tem um periférico ligado a um
barramento privado…)
Se existem diversos processadores idênticos pode-se tentar balancear a carga entre eles.
O usual é existir uma fila de processos prontos comum a todos os processadores. Esses
processos são atribuídos a qualquer processador
que esteja livre.
Nesta situação é normal cada processador ser 'auto-escalonável' (cada processador
sempre que esta livre vai buscar um processo à fila partilhada). É necessário garantir que dois
processadores não ficam com o mesmo processo…
Para evitar estas situações nalguns sistemas um dos processadores faz o escalonamento
para os outros (sistemas tipo master-slave…). No limite toda a actividade do sistema
operativo pode ficar dedicada a um processador e os outras apenas servirem para executar
código do utilizador.
Os sistemas assimétricos são bastante mais simples que os simétricos uma vez que
apenas um processador acede aos dados do sistema não sendo necessária qualquer
partilha…

10.4 Escalonamento em sistemas tempo-real


 Tal como já vimos os sistemas tempo real podem ser divididos em: 'Hard real-time' e 'Soft
real-time'.

Sistemas Hard
 Os sistemas Hard garantem que uma determinada tarefa ou processo pode ser executada
num determinado intervalo de tempo.
 Assim, normalmente, quando se submete um processo ao sistema indica-se
também o intervalo de tempo em que este deve ser executado. O algoritmo de escalonamento
(scheduler) aceita o processo (garantindo o tal intervalo de tempo) ou recusa o processo por
não conseguir garantias de execução no tal intervalo.
 Para que o scheduler possa dar a resposta anterior é necessário que ele consiga

Ficha1- 1 a 5 Sistemas Operativos pagina 44


UDM Tema: Introdução aos Sistemas Operativos

calcular qual a carga de cada recurso do sistema (CPU, IO, etc.) durante o tal intervalo de
tempo. Ou seja o SO terá que efectuar reservas de recursos. Para tal o SO terá de saber
quanto tempo é que demora cada funcionalidade…
 Na maior parte dos casos a situação anterior é muito difícil de se conseguir,
nomeadamente quando o sistema tem dispositivos secundários de armazenamento ou utiliza
memória virtual… (devido à impossibilidade de determinar o tempo que estes subsistemas
demoram a efectuar as suas operações)
 Por estas razões é que estes sistemas são implementados em hardware e
software especial com bastantes funcionalidades diminuídas relativamente aos SO genéricos.

Sistemas Soft
 Este tipo de sistemas apenas garante que determinados processos mais críticos terão
uma prioridade superior aos outros.
 Neste cenário os processos com menor prioridade podem executar de forma bastante mais
lenta e ter dificuldades no acesso a recursos utilizados pelos processo prioritários.

 É fundamental que os sistemas prioritários (dentro do limite possível) não sejam afectados
pelo aumento da carga noSO…
 Para garantir que o SO tem tempos de resposta adequados para os processos
em tempo real é necessário que muitas das vezes processos menos prioritários sejam
interrompidos, mesmo quando o SO está a executar alguma função para eles.
 Assim quando o SO é interrompido no meio da execução de uma
funcionalidade sua para um processo menos prioritário ele tem que reservar os dados que
estava a manipular de forma a que outro processo não os altere e que estes estejam no
mesmo estado quando este retornar a executar o tal processo menos prioritário.
Isto levanta a questão do que é que acontece quando o processo mais prioritário
também necessita de aceder aos tais dados que ficaram reservados.
 Nesta situação usual é o sistema efectuar uma inversão temporária de
prioridades. Isto consiste em o processo menos prioritário herdar a prioridade do processo
mais prioritário até ao final da utilização do recurso. Assim que termina essa utilização a sua
prioridade volta ao normal.

10.5 Avaliação de algoritmos


 Como seleccionar o melhor algoritmo de escalonamento para um sistema?
 Em primeiro lugar é necessário seleccionar qual a importância dos diversos critérios
possíveis (tempo de resposta, utilização de CPU, turnaround time, etc).
 Depois de estabelecida a importância dos critérios é necessário avaliar o desempenho do
sistema segundo esses critérios para os diversos algoritmos em causa.
 Existem várias hipóteses, desde a mais simples até à mais complexa:

Ficha1- 1 a 5 Sistemas Operativos pagina 45


UDM Tema: Introdução aos Sistemas Operativos

Modelação determinística (método analítico)


Consiste basicamente em utilizar dados de entrada e em função destes dados calcular qual o
resultado para os diversos algoritmos.
 É um sistema muito simples mas também bastante limitado uma vez que os dados de
entrada podem não representar bem o sistema em causa.
 Na realidade só são utilizáveis para situações em que o SO esteja sempre a executar os
mesmos programas…
Modelos de filas
Como normalmente os processos que executam num SO vão sempre variando é difícil
utilizar o tal modelo determinístico.
 Consegue-se determinar (ou estimar) a distribuição da carga de CPU e IO.
 Chega-se normalmente a formulas matemáticas que descrevem a probabilidade de um
burst de CPU ou de IO.
 Consegue-se também chegar à distribuição da chegada de processos ao sistema.
 Desta forma é possível calcular uma média de tempo de espera, utilização de CPU, etc.…
 O sistema é descrito como uma rede de servidores e respectiva fila de processos em
espera (CPU, IO).
 Sabendo as taxas de chegada de processos ao sistema assim como os tempos de
serviço e possível calcular os tempos de utilização , espera, etc.
 Este método pode tornar-se bastante complexo e como normalmente é necessário
efectuarem-se suposições pode tornar-se um método pouco
realista…
Simulações
 A simulação consiste na implementação de um modelo que emule o sistema real.
 Nestes modelos são representados os componentes do SO que interessam avaliar.
 Os dados para a simulação são normalmente gerados por uma rotina de geração de
números aleatórios que servirá para gerar processos, CPU burst times, etc. Esta
geração é baseada normalmente em funções de distribuição probabilística (uniforme,
exponencial, poisson…) ou então de forma empírica.
 Embora este modelo seja interessante tem alguns problemas como por exemplo
consegue-se especificar a frequência de eventos mas não a sua ordem…o que
é torna o modelo pouco realista…

Implementação
 No limite o que se pode efectuar é testar os respectivos algoritmos no próprio sistema
real e efectuar medições…
 Esta solução apesar de ser a mais exacta é também a mais custosa e de certa forma na
maior parte das situações é impraticável…

Ficha1- 1 a 5 Sistemas Operativos pagina 46


UDM Tema: Introdução aos Sistemas Operativos

Exercícios sobre Escalonamento


1.Considere o seguinte conjunto de processos (duração do burst time em milisegundos)

Processo Burst time Prioridade


P1 10 3
P2 1 1
P3 2 3
P4 1 4
P5 5 2
Assuma que os processos chegam pela ordem P1, P2, P3, P4, P5, todos no tempo 0.
a) Desenhe quatro diagramas de Gantt ilustrando a execução destes processos usando os
algoritmos FCFS, SJF, prioridade e RR (time slice=1).
b) Qual é o turnaround para cada um dos processos em cada um dos algoritmos?
c)Qual é o tempo de espera para cada processo em cada um dos algoritmos?
d) Qual dos algoritmos obtém um melhor tempo de espera médio?
2.Suponha que os seguintes processos entram no sistema para execução nos tempos
indicados. Cada processo executará durante o tempo indicado.
Ao responder às questões utilize escalonamento não-preemptive e fundamente as suas
respostas na informação disponível na altura em que a decisão deve ser efectuada.

Tempo de
Processo Burst Time
Chegada
P1 0.0 8
P2 0.4 4
P3 1.0 1

a) Qual é o tempo médio de turnaround para estes processos utilizando um algoritmo


FCFS?
b) Qual é o tempo médio de turnaround para estes processos utilizando um algoritmo
SJF?
c) O método SJF é um método que deveria dar a melhor solução.
Note-se que na altura 0 apenas tínhamos o processo P1 na fila de processos prontos.
Calcule a diferença em termos de tempo médio de turnaround se o CPU ficar 'parado'
na primeira unidade temporal e utilizando SJF. Lembre-se que o processo P2 e P3 vão
estar a espera durante o tempo em que o CPU está parado (o seu tempo de espera vai
aumentar…). Este algoritmo podia ser designado por ' escalonamento baseado em
conhecimento futuro'.
12 Comunicação entre Processos
12.1 Processos Cooperativos
 Os processos concorrentes que executam num sistema operativo podem ser
independentes ou cooperativos.
 Um processo é independente se não pode afectar ou ser afectado por outros processos
em execução no sistema.
 Qualquer processo que não partilhe dados com outro processo é independente.
 Um processo é cooperativo se pode ser afectado ou afectar outros processos do

Ficha1- 1 a 5 Sistemas Operativos pagina 47


UDM Tema: Introdução aos Sistemas Operativos

sistema.
 Qualquer processo que partilhe dados com outro processo é um processo cooperativo.
 Algumas razões que justificam um ambiente que permita processos cooperativos
 Partilha de informação. (Ex: partilha do acesso a um ficheiro)
 Melhoria de desempenho. Através da divisão das tarefas.
Só possível se existirem múltiplos recursos (CPU, IO, etc.).
 Modularidade. Dividir o sistema em módulos.
 Conveniência. Os utilizadores vão desejar trabalhar em múltiplas tarefas ao mesmo
tempo…
 A execução concorrente que requer cooperação entre processos vai necessitar de
mecanismos que permitam que os processos comuniquem entre si e mecanismos para
sincronização das tarefas dos processos.
 Existem inúmeros exemplos possíveis de cooperação entre processos nomeadamente
cooperação do tipo produtor-consumidor em que um processo vai produzindo dados
(processo produtor) para um processo consumidor. (Exemplo: programa de impressão
produz output que o driver da impressora vai consumindo)

12.2 Comunicação entre Processos


 Os sistemas operativos disponibilizam mecanismos de comunicação entre processos que
permitem a troca de dados entre processos assim como a sincronização das suas tarefas.
 Na maior parte dos casos esses mecanismos baseiam-se em sistemas de transmissão de
mensagens e sistemas de partilha de memória.
 Estes sistemas de transmissão de mensagens permitem a troca de dados sem se recorrer a
variáveis partilhadas.
 Existem basicamente dois tipos de funções que suportam este mecanismo:
send(mensagem) e receive(mensagem).
Algumas considerações relativas à troca de mensagens entre processos…
 Como são estabelecidas as ligações entre os dois processos? Pode uma ligação ser
estabelecida entre mais do que dois processos?
 Quantas ligações podem existir entre cada par de processos? Qual a capacidade de uma
ligação? Ou seja, a ligação tem algum tipo de buffer?
 Qual o tamanho das mensagens? Pode a ligação suportar mensagens de tamanho variável
ou tamanho é fixo?
 A ligação é bidireccional ou unidireccional?
 Existem ainda várias formas para estabelecimento das referidas ligações e operações de
send/receive…
 Comunicação directa ou indirecta.
 Comunicação simétrica ou assimétrica
 Buffering automático ou explicito.
 Envio por cópia ou por referência.

Ficha1- 1 a 5 Sistemas Operativos pagina 48


UDM Tema: Introdução aos Sistemas Operativos

 Mensagens de tamanho fixo ou variável

12.2.1 Naming (identificação)


 Os processos que comunicam entre si têm de ter uma forma de se identificarem.
 Relativamente a este aspecto podemos ter comunicação directa ou indirecta .

12.2.1.1 Comunicação directa


 Nesta forma de comunicação cada ponto da comunicação deve identificar-se
explicitamente.
 Assim as funções de comunicação passam a ser:
Send(P, mensagem) --- Envia uma mensagem para o processo P.
Receive(Q, mensagem)--- Recebe uma mensagem do processo Q.
Neste caso:
 É estabelecida uma ligação automaticamente entre cada par de processos que desejam
comunicar. Os processo apenas têm que saber a identificação de cada um.
 É estabelecida uma ligação entre dois processos.
 Entre cada par de processo existe apenas uma ligação.
 A ligação pode ser unidireccional mas na maior parte dos casos é bidireccional.
 Esta forma de comunicação implica uma simetria em termos de endereçamento; emissor
e receptor têm que saber o nome um do outro para comunicarem.
 Existe uma variante desta situação que permite uma assimetria em termos de
endereçamento.
 Nesta variante apenas o emissor conhece o receptor. O receptor não necessita de
conhecer o emissor.
Assim:
Send(P, mensagem) -> Envia a mensagem para o processo P
Receive(id, mensagem) -> Recebe uma mensagem de qualquer processo; a variável id
retorna a identificação do processo que enviou a mensagem.
 Em qualquer uma destas situações anteriores é necessária alguma forma de
identificação dos processos comunicantes.
12.2.1.2 Comunicação indirecta
 Neste tipo de comunicação as mensagens são enviadas e recebidas através de
'caixas de correio' (mailboxes).
 Uma caixa de correio pode ser vista como um objecto no qual os processo podem
depositar e ler mensagens…
 Cada caixa de correio tem uma identificação.
 Dois processos podem comunicar via uma caixa de correio partilhada…
Send(A, mensagem) ---- Envia a mensagem para a caixa de correio A.
Receive(A, mensagem) ---- Recebe uma mensagem da caixa de correio A.

Ficha1- 1 a 5 Sistemas Operativos pagina 49


UDM Tema: Introdução aos Sistemas Operativos

Nesta situação a ligação tem as seguintes propriedades:


 É estabelecida uma ligação entre dois processos se partilham uma caixa de correio
 Pode ser estabelecida uma ligação entre mais dos que dois processos
 Entre dois processos podem existir várias ligações, cada ligação correspondendo a uma
caixa de correio
 Uma ligação pode ser unidireccional ou bidireccional.
 Uma caixa de correio pode ser detida por um processo ou pelo sistema operativo.
 Se a caixa de correio é detida por um processo então este pode receber mensagens da
caixa e os outros processos podem enviar mensagens. Neste caso não há dúvidas sobre o
processo que recebe as mensagens.
 Quando o processo 'dono' da caixa de correio termina a caixa também é destruída.
 Uma caixa de correio que seja detida pelo SO tem uma existência idenpendente dos
processos.
Neste caso o SO deve providenciar mecanismos para:
 Criar uma nova caixa de correio
 Enviar e receber mensagens de uma caixa de correio
 Destruir a caixa

12.2.2 Buffering
 Uma ligação tem uma determinada capacidade que determina o número de
mensagens que esta pode conter temporariamente.
 Esta característica pode ser vista como uma fila/lista de mensagens.
Basicamente três formas de implementar esta fila:
 Capacidade zero. Quer dizer que a ligação não pode conter mensagens. Ou seja, o
emissor tem de esperar que o receptor receba a mensagem.
 Capacidade limitada. A fila tem uma capacidade para n mensagens. Se a fila
estiver cheia o emissor tem que esperar até que haja espaço na fila.
 Capacidade ilimitada . A fila é potencialmente ilimitada. O emissor nunca espera.
Note-se que nos dois casos de capacidade diferente de zero o emissor não tem
conhecimento se a mensagem chegou ao destino.
Uma possibilidade para ultrapassar esta situação:
Processo P:
Send (Q, mensagem)
Receive (Q, mensagem)
Processo Q:
Receive(P, mensagem)
Send(P, "confirmação");
Este é um exemplo de comunicação assíncrona .
Existem sistemas em que o send é alterado de forma a que o processo que o executa fica
bloqueado até receber a mensagem de confirmação. Nestes casos o receive não bloqueia.

Ficha1- 1 a 5 Sistemas Operativos pagina 50


UDM Tema: Introdução aos Sistemas Operativos

Estamos perante uma comunicação síncrona .


Este método de comunicação síncrona pode ser facilmente expandido, tornando-se num
sistema de chamada remota de procedimentos (Remote Procedure Call - RPC).
Um sistema RPC é baseado no pressuposto que uma sub rotina ou procedimento num
sistema uniprocessador actua exactamente como um sistema de mensagens no qual o emissor
fica bloqueado até receber a resposta/confirmação.
A mensagem é então equivalente a uma chamada a uma subrotina. A mensagem de
resposta contém o resultado da subrotina.
Assim a evolução seguinte é a possibilidade de processos concorrentes poderem
chamar rotinas uns dos outros via o mecanismo RPC (no mesmo computador ou em
computadores diferentes…).

13 Comunicação entre Processos (UNIX)


13.1 Pipes
Os Pipes são mecanismos de comunicação entre processos que permitem que dois ou mais
processos troquem informação.
Um exemplo comum é a sua utilização para ligar o standard output de um programa ao
standard input de outra.
Exemplo:
$ who | wc -1
Permite contar o numero de utilizadores no sistema
Ambos os processos (produtor e consumidor) executam concorrentemente.
O pipe implementa o bufferring dos dados entre o consumidor e o produtor.

Ficha1- 1 a 5 Sistemas Operativos pagina 51


UDM Tema: Introdução aos Sistemas Operativos

O produtor fica suspenso no caso do buffer ficar cheio.


O consumidor fica suspenso no caso do buffer estar vazio.

13.1.1 Unnamed Pipes


São ligações unidireccionais com buffering automático e limitado (dependendo da
implementação 4Kbytes ~ 40Kbytes)
Instrução: int pipe ( int fd[ ] )
Esta instrução cria um unnamed pipe e retorna dois descritores de ficheiros; um
associado ao read (fd[0]) e outro associado ao write (fd[1]).

fd[0]

fd[1]
write
pipe

read

Algumas considerações…
 Se um processo lê de um pipe cujo write tenha sido fechado o read() retorna 0, indicando
o fim do input.
 Se um processo lê um pipe vazio cujo write ainda esteja aberto essa processo adormece
(sleep) ate que o pipe tenha dados.
 Se um processo tenta ler mais bytes que os que se encontram no pipe o SO retorna todo o
conteúdo do pipe e a instrução read() retorna o número de
bytes realmente lidos.
 Se um processo escreve para um pipe cujo read esteja fechado o write() falha e o
processo recebe um sinal do tipo SIGPIPE. A acção default deste sinal é a de terminar o
processo que recebe o sinal.
 Se um processo escreve mais bytes que a capacidade do buffer do pipe o SO não
garante que o processo não seja 'retirado' do CPU (preempted)
 Como os unnamed pipes funcionam via o mecanismo de descritores de ficheiros apenas
o processo que criou o pipe e os seus descendentes podem usar o pipe.
 A instrução lseek() não tem significado relativamente a um pipe.

Sequência usual de instruções:


 O processo pai cria o pipe usando pipe().
 O processo pai executa um fork().
 O produtor (processo que escreve) fecha a extremidade read do pipe e o processo
consumidor (processo que lê) fecha a extremidade write do pipe.
 Os processos comunicam utilizando as instruções write() e read().

Ficha1- 1 a 5 Sistemas Operativos pagina 52


UDM Tema: Introdução aos Sistemas Operativos

 Cada processo fecha os respectivos descritores de ficheiros após terminarem a


comunicação.
Nota: A comunicação bidereccional só é possível pela utilização de dois pipes.

13.1.2 Named Pipes


 Os named pipes (também conhecidos por FIFOs) tem as seguintes vantagens
relativamente aos unnamed pipes:
 Possuem um nome com existência no sistema de ficheiros
 Podem ser utilizados por processos sem qualquer relação directa
 Existem até serem explicitamente destruídos
Como existem no sistema de ficheiros podem ser criados através da função mknod (opção
p).
Exemplo via shell:
 mknod myPipe p
Por programação:
 mknod("myPipe", S_IFIFO, 0);
 chmod("myPipe", 0660); /* alterar a permissão */
 Utilizar open() para abrir o pipe.
 Utilizar write() para escrever para o pipe.
 Utilizar read() para ler do pipe.
 Utilizar close() quando já não se necessitar do pipe.
 Utilizar unlink() para remover definitivamente o pipe do sistema de ficheiros.
Nota: Tal como os unnamed pipes também os named pipes só permitem um sentido em
termos de comunicação.
 O Processo produtor deve abrir o pipe em write-only e o processo consumidor deve abrir
o pipe em read-only.
 Note-se que caso não se especifique nada na abertura do pipe este 'bloqueia' o processo
que escreve ou lê até o pipe ter ligação na outra extremidade…

13.2 Sinais
Os Sinais são normalmente utilizados como resposta a acontecimentos inesperados ou
imprevisíveis, como:
 erros de cálculos em virgula flutuante,
 erros de provocados por problemas na fonte de alimentação do computador,
 'morte' de um processo filho,
 pedidos de interrupção do utilizador (control-C),
 etc.…

Ficha1- 1 a 5 Sistemas Operativos pagina 53


UDM Tema: Introdução aos Sistemas Operativos

Este tipo de eventos são normalmente designados por interrupções uma vez que implicam a
interrupção do processamento normal para uma resposta adequada…
 Quando o SO reconhece o acontecimento de alguma destas situações envia o
respectivo sinal ao processo em causa.
 Cada um destes eventos tem número que permite identificar o sinal.
 Não é apenas o SO que pode enviar sinais.
 Qualquer processo pode enviar sinais.
 O processo que recebe o sinal pode ignorá-lo ou processá-lo.
Para processar o sinal o processo tem que especificar uma rotina/função designada
por signal handler.
 Os processamentos default para os sinais são:
 Terminar o processo e gerar um ficheiro core (dump)
 Terminar o processo sem gerar um ficheiro core (quit)
 Ignorar o sinal (ignore )
 Suspender o processo (suspend)
 Continuar o processo
 A função alarm() permite que o processo receba um sinal to tipo SIGALRM após um
determinado intervalo temporal. A acção default deste tipo de sinal é terminar o processo.
unsigned int alarm ( unsigned int count ) count é o intervalo em segundos.
Responder aos sinais…
 A função signal() pode ser utilizada para especificar uma rotina de resposta ao sinal que
substitui a rotina default do SO.
 A função signal tem dois parâmetros: o numero do sinal que se vai ‘reprogramar’ e a
nova função.
 O valor da função pode ser:
 SIG_IGN, para que o sinal seja ignorado
 SIG_DFL, para que seja utilizada a acção default do SO
 Ou o endereço de uma função que será utilizada para processar o sinal.
 Esta função não leva parâmetros e não retorna valores.
 A função pause() permite que um processo fique suspenso até receber um sinal.
Envio de sinais…
É possível o envio de sinais entre dois processos através da função kill() (note-se que a
função chama-se kill pois nas primeiras versões do unix esta função só servia para enviar
sinais para terminar processos…)
 Esta função tem dois parâmetros:
 Pid identifica o processo que irá receber o sinal
 SigCode identifica o sinal a enviar

Ficha1- 1 a 5 Sistemas Operativos pagina 54


UDM Tema: Introdução aos Sistemas Operativos

 Para que a função kill tenha sucesso o processo que envia o sinal e o que recebe devem
ter o mesmo dono (utilizador) ou o dono do processo que envia é um super-user.

Ficha1- 1 a 5 Sistemas Operativos pagina 55

Você também pode gostar