Escolar Documentos
Profissional Documentos
Cultura Documentos
programas
Sistema Operativo
Hardware do 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.
_________________________________________________________________________
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.
_________________________________________________________________________
Eng AACucko 2023 Página 7
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
_________________________________________________________________________
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...
_________________________________________________________________________
Eng AACucko 2023 Página 14
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
Hardware…
_________________________________________________________________________
Eng AACucko 2023 Página 17
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
OS/2
POSIX
Subsytem
Subsytem
Security
Win32
Subsytem
Subsytem
User
Mode
Kernel
Mode
Executive Services
Kernel
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.
_________________________________________________________________________
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…
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
_________________________________________________________________________
Eng AACucko 2023 Página 21
Universidade Técnica de Moçambique Sistemas Operativos Fichas 1 a 4
_________________________________________________________________________
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.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
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.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…)
7.5 Threads
7.5.1 Criação de threads
OS/400
MI
Este novo modelo assenta nos seguintes conceitos: Módulos: têm um ou mais procedimentos
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.
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
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.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:
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.
P2 P5 P1 P3 P4
0 1 6 16 18 19
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.
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.
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
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.
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…
Tempo de
Processo Burst Time
Chegada
P1 0.0 8
P2 0.4 4
P3 1.0 1
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.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.
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.
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.…
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
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.