Você está na página 1de 19

Sumário

7.6.8.8.1 Semáforos.....................................................................................2
7.6.8.8.2 Monitores .....................................................................................3
7.6.8.9 Troca de Mensagens........................................................................5
7.6.8.10 Deadlock........................................................................................7
7.6.8.10.1 Prevenção de Deadlock ..............................................................8
7.6.8.10.2 Detecção do Deadlock................................................................9
7.6.8.10.3 Correção de Deadlock ..............................................................10
8. Gerência de Processador................................................................................................... 10
8.1 Critérios de Escalonamento ........................................................................................ 11
8.1.1 Utilização da UCP............................................................................11
8.1.2 Throughput .......................................................................................11
8.1.3 Tempo de Turnaround......................................................................11
8.1.4 Tempo de resposta............................................................................11
8.2 Escalonamento Não-preenptivo...................................................................................... 12
8.2.1 Escalonamento First-In-First-Out (FIFO) ............................................................... 12
8.2.2. Escalonamento Shortest-Job-First (SJF) ................................................................ 13
8.2.3 Escalonamento Cooperativo .................................................................................... 14
8.3 Escalonamento Preemptivo ............................................................................................ 14
8.3.1 Escalonamento Circular........................................................................................... 14
8.3.2 Escalonamento por Prioridades ............................................................................... 15
8.3.3 Escalonamento por Múltiplas Filas ......................................................................... 16
8.3.3.1 Escalonamento por Múltiplas Filas com Realimentação ..............17
8.3.4 Escalonamento de Sistemas de Tempo Real ........................................................... 18
8.3.5 Escalonamento com Múltiplos Processadores......................................................... 18
7.6.8.8.1 Semáforos
Um semáforo é uma variável inteira, não negativa, que só pode ser manipulada por
duas instruções: DOWN e UP, também chamadas, originalmente, instruções P e V.
No caso da exclusão mutua, as instruções DOWN e UP funcionam como protocolos
de entrada e saída, respectivamente, para que um processo possa entrar e sair de usa região
crítica. O semáforo foi associado a um recurso compartilhado, indicando quando o recurso
está sendo acessado por um dos processos concorrentes. Se seu valor for maior que O,
nenhum processo está utilizando o recurso; caso contrário, o processo fica impedido.
Sempre que um processo deseja entrar em sua região crítica ele executa uma instrução
DOWN.
Isso quer dizer que o valor era 0, para que outro não entre nesta região é feito um
decremento de 1. Caso outro processo deseje executar sua região crítica e valor seja igual a
0, o processo ficará no estado de espera, em um fila associada ao semáforo.
O processo que está acessando sua região crítica, executa uma instrução UP,
incrementando o semáforo de 1 e liberando o acesso ao recurso.
Essas operações são indivisíveis; assim, é garantido que, se uma das operações for
iniciada, nenhum outro processo poderá ter acesso ao semáforo até o término dessa
operação. Normalmente as instruções DOWN e UP são implementadas como rotinas do
sistema (system calls), com o sistema desabilitando todas as interrupções para a execução
exclusiva das instruções.
Semáforos aplicados ao problema de exclusão mútua são chamados mutexes
(mutual exclusion semaphores) ou binários, (por apenas assumirem os valores) 0 e 1.
Além de permitirem a solução da exclusão mútua, os semáforos podem ser
utilizados para implementar a sincronização condicional. Em geral, se existe um processo
que deve ser modificado sobre a ocorrência de um evento e também existe outro capaz de
detectar sua ocorrência, podemos utilizar um semáforo associado ao evento esperado para
sincronizar ambos os processos.
Semáforos do tipo Vazio e Cheio são chamados de semáforos contadores, sendo
bastante úteis quando aplicados na alocação de recursos do mesmo tipo (pool). O semáforo
é inicializado com o número total do pool, e, sempre que um processo deseja um recurso,
executa um DOWN, subtraindo 1 do número de recursos disponíveis. Da mesma forma
sempre que libera um recurso para o pool, executa um UP. Se o semáforo contador ficar
igual a 0, isso significa que não existem mais recursos a serem utilizados, e o processo eu
solicitou o recurso permanece esperando, até que outro processo libere algum recurso para
o pool.
7.6.8.8.2 Monitores
O uso de semáforos exige do programador muito cuidado, pois qualquer engano
pode levar a problemas de sincronização imprevisíveis e difíceis de reproduzir, devido à
execução concorrente dos processos. Monitores são mecanismos de sincronização de alto
nível, que tentam tornar mais fáceis o desenvolvimento e a correção de programas
concorrentes.
O monitor é um conjunto de procedimentos, variáveis e estrutura de dados definidos
dentro de um módulo. Sua característica mais importante é a implementação automática da
exclusão mútua entre seus procedimentos, ou seja, somente um processo pode estar
executando um dos procedimentos do monitor em um determinado instante. Toda vez que
um processo chama um desses procedimentos, o monitor verifica se já existe outro processo
executando algum procedimento do monitor.
As variáveis globais do monitor são visíveis apenas a ele e a seus procedimentos. O
bloco de comandos do monitor é responsável por inicializar essas variáveis, sendo
executado apenas uma vez, na ativação do programa onde está declarado o monitor. A
estrutura de um monitor é mostrada a seguir, utilizando uma sintaxe Pascal não
convencional.
Toda implementação da exclusão mútua nos monitores é feita pelo compilador, e
não mais pelo programador, como no caso do uso de semáforos. Para isso, basta colocar
todas as regiões criticas em forma de procedimentos no monitor e o compilador se
encarregará de garantir a exclusão mútua desses procedimentos. Assim, o desenvolvimento
de programas concorrentes fica mais fácil e as chances de erro são menores.

O monitor não pode ser executado com uma sub-rotina. A comunicação do processo
com o monitor é feita unicamente através de chamadas a seus procedimentos e dos
parâmetros passados para eles.
A implementação da sincronização condicional não é tão simples quanto à da
exclusão mútua.
Para implementá-la, é necessário utilizar variáveis de condição e duas instruções
que operam sobre elas: WAIT e SIGNAL.
Uma variável de condição é uma estrutura de dados do tipo fila, onde os processos
esperam por algum evento. Sempre que o monitor descobre que alguma condição impede a
continuação da execução de um processo, ele realiza um WAIT, fazendo com que o
processo fique no estado de espera na fila associada a essa condição. Uma característica do
monitor é permitir que um ou mais processos estejam no estado de espera dentro do
monitor.
O processo bloqueado só poderá prosseguir sua execução quando um outro processo
executar um SIGNAL, sobre a mesma condição que o colocou no estado de espera. Nesse
caso, é possível que haja vários processos esperando em uma mesma fila. Um problema
decorrente desse mecanismo é a possibilidade de dois processos estarem executando
procedimentos diferentes dentro do monitor ao mesmo tempo. Para evitar esse problema,
deve-se sempre colocar o comando SIGNAL como sendo o último comando do
procedimento. Assim, o processo, após executar o SIGNAL, abandona o monitor
imediatamente.
Como os monitores são baseados em comandos de uma linguagem de programação,
o compilador da linguagem deve ser capaz de reconhecê-los e implementá-los. São raras as
linguagens que permitem a implementação de monitores, podendo ser citadas, entre elas, a
Concurrent Euclid e o Pascal Concorrente.

7.6.8.9 Troca de Mensagens


É um mecanismo de comunicação e sincronização entre processos, implementado
pelo sistema operacional através de duas rotinas do sistema: SEND e RECEIVE. A rotina
SEND é responsável por evitar uma mensagem para um processo receptor, e a RECEIVE
por receber uma mensagem de um processo transmissor. O procedimento pode ser
representado da seguinte maneira:
SEND (Transmissor, Mensagem);
RECEIVE (Receptor, Mensagem);
Os procedimentos SEND e RECEIVE, mesmo não sendo suas execuções
mutuamente exclusivas, permitem tanto a comunicação entre processos como a
sincronização entre eles. A comunicação ocorre porque um processo, ao receber uma
mensagem obtém dados de outro processo. A sincronização é obtida porque uma
mensagem somente pode ser lida após ter sido enviada, restringindo, dessa forma, a ordem
na qual os dois eventos devem ocorrer.
A comunicação por troca de mensagens possui muitos problemas, como, por
exemplo, a perda de uma mensagem. Para garantir que uma mensagem não se perca, o
processo receptor, ao recebê-la, deve enviar ao processo transmissor uma mensagem de
recebimento (ACK). Caso o transmissor não receba um ACK em um determinado intervalo
de tempo, ele retransmite a mensagem.
A comunicação entre processos poder ser feita diretamente, bastando que o processo
que deseja enviar ou receber uma mensagem enderece explicitamente o nome do processo
receptor ou transmissor.
Uma característica do endereçamento direto é que este só permite a comunicação
entre dois processos.
Seu maior problema é, justamente, a necessidade da especificação do nome dos
processos envolvidos na troca de mensagens, o que pode restringir a utilização dessa forma
de comunicação.
O Endereçamento indireto utiliza uma área compartilhada, onde as mensagens
podem ser colocadas pelo processo transmissor e retiradas pelo receptor. Esse tipo de buffer
é conhecido como mailbox. No endereçamento indireto, vários processos podem estar
associados a mailbox, e os parâmetros dos procedimentos SEND e RECEIVE passam a ser
nomes de mailboxes e não mais nomes de processos.

Independentemente da forma de endereçamento entre os processos, a comunicação


entre ele pode bloquear ou não o processo envolvido. Basicamente, existem duas formas de
comunicação entre processos através da troca de mensagens: comunicação síncrona e
comunicação assíncrona.
A comunicação é dita síncrona, quando um processo envia uma mensagem e fica
esperando, até que o processo receptor leia a mensagem ou quando um processo tenta
receber uma mensagem e permanece esperando, até que o processo transmissor grave
alguma mensagem.
Na comunicação assíncrona, nem o receptor permanece aguardando o envio de uma
mensagem, nem o transmissor o seu recebimento. Nesse caso, além da necessidade de
buffers para armazenar as mensagens, deve haver outro mecanismo para controlar o
sincronismo permitindo assim identificar o processo que enviou uma mensagem ou
recebeu.
A grande vantagem da comunicação assíncrona é o maior paralelismo na execução
dos processos, comparado à comunicação síncrona, onde a necessidade de espera dos
processos reduz o grau de concorrência.

7.6.8.10 Deadlock
Isto ocorre quando se está esperando por um processo que nunca ocorrerá. Essa
situação é conseqüência, na maioria das vezes, do compartilhamento de recursos do sistema
entre vários processos, sendo que cada processo deve ter acesso ao recurso de forma
exclusiva (exclusão mútua).
Para que ocorram situações de diadlock em um sistema, são necessárias pelos menos quatro
condições:
1. Cada recurso só pode estar alocado a um único processo em um determinado
instante (exclusão mútua);
2. Um processo, além dos recursos já alocados, pode estar esperando por outros
recursos;
3. Um mecanismo não pode ser liberado de um processo só porque outros processos
desejam o mesmo recurso (não-preenpção);
4. Um processo pode ter de esperar por um recurso alocado a outro processo e vice
versa (espera circular).
O problema de diadlock existe em qualquer sistema operacional multiprogramável, no
entanto, as soluções implementadas devem considerar o tipo do sistema e o impacto em seu
desempenho.

7.6.8.10.1 Prevenção de Deadlock


Para preveni-lo é preciso garantir que uma das quatro condições necessárias para
sua ocorrência nunca se satisfaça.
A ausência da primeira condição (exclusão mútua) certamente acaba com o
problema do diadlock, pois nenhum processo terá que esperar para ter acesso a um recurso
mesmo que já esteja sendo utilizado por outro processo. Mas isso não pode fazer, pois
como já vimos causaria inconsistências sérias em nível dos processos do sistema.
Na segunda condição, se puder evitar que os processos que já possuam recursos
garantidos requisitem novos recursos, também evitaremos o problema de deadlock. Uma
maneira de implementar esse mecanismo de prevenção é, sempre que um processo
necessitar de recursos para executar, que ele os requisite antes de começar sua execução. Se
todos os recursos necessários ao processo estiverem disponíveis, o processo poderá alocá-
los e iniciar sua execução. Caso contrario nenhum recurso será alocado e o processo ficará
no estado de espera. Mas isso pode gerar grande desperdício na utilização dos recursos do
sistema, como também pode dificultar para se determinar o número de recursos que um
processo deverá alocar antes da sua execução. No entanto o mais grave nesse método é a
possibilidade de um processo sofrer starvation, ou seja, todos os recursos necessários a sua
execução nunca estarem disponíveis ao mesmo tempo.
A terceira condição pode ser evitada quando permitimos que um recurso seja
retirado de um processo, no caso de outro processo necessitar do mesmo recurso. Dessa
forma, eliminaremos o problema de deadlock. Ma como nas outras condições esta também
pode ocasionar sérios problemas, podendo até fazer o processo perder todo o
processamento até então realizado e como na segunda condição outro problema e o mais
grave é a possibilidade de ocorrer stravation, quando o processo garante alguns recursos
necessários á sua execução e o sistema os libera em seguida.
A última maneira de evitar um deadlock é excluir a possibilidade da espera circular
(quarta condição). Uma forma de implementar esse mecanismo é forçar o processo ter
apenas um recurso de cada vez. Se necessitar de outro recurso, deve liberar o primeiro.
Vimos que se evitarmos a ocorrência de qualquer uma das quatro condições, o
compartilhamento de recursos do sistema ficará limitado em função de diversas restrições.
Mas é possível evitar o deadlock? A solução mais conhecida para essa situação
talvez seja o Algoritmo do Banqueiro. Basicamente, este algoritmo exige que os processos
informem o número de cada tipo de recurso necessário para sua execução. Com essas
informações, é possível definir o estado de alocação de um recurso, que é a relação entre o
número de recursos alocados e disponíveis, e o número máximo de processos que
necessitam desses recursos.
Apesar de evitar o problema de deadlock ela também possui varias limitações. A
maior delas é a necessidade de um número fixo de processos ativos e de recursos
disponíveis no sistema. Com essa limitação fica difícil implementar essa solução, pois é
muito difícil prever o número de usuários no sistema e o número de recursos disponíveis.

7.6.8.10.2 Detecção do Deadlock


Em sistemas que não tenham um mecanismo de prevenção de deadlock é necessário
um mecanismo para sua detecção e correção do problema. E isso que dizer que temos que
ter um mecanismo que realmente, determine a existência de um deadlock.
Os sistemas operacionais devem der uma estrutura de dados capazes de identificar
cada recurso do sistema, o processo que o está alocando e os processos que estão à espera
da liberação do recurso.
Toda vez que um recurso é alocado ou liberado por um processo, a estrutura deve
ser atualizada.
Dependendo do tipo de sistema, o ciclo de busca de um deadlock pode variar. Em
sistemas de tempo compartilhado, o tempo de busca pode ser maior, sem comprometer o
desempenho e a confiabilidade do sistema. Sistemas de tempo real, por sua vez, devem
constantemente certificar-se da ocorrência de deadlocks, porém essa maior segurança gera
mais overhead no sistema.
7.6.8.10.3 Correção de Deadlock
Após sua detecção o sistema deverá corrigir o problema. Uma solução bastante
utilizada pela maioria dos sistemas operacionais é, simplesmente, eliminar um ou mais
processos envolvidos no deadlock e desalocar os recursos já garantidos por eles, quebrando,
assim, a espera circular.
A eliminação dos processos envolvidos no deadlock e, conseqüentemente, as
liberações de seus recursos podem não ser simples, dependendo do tipo de recurso
envolvido.
9 • Um processo estiver atualizando um arquivo ou imprimindo uma listagem, o
sistema deve garantir que esses recursos sejam liberados sem problemas.
9 • Processos eliminados não têm como ser recuperados
9 • Outros processos, que antes estavam em deadlock, poderão prosseguir.
A escolha dos processos é feita, normalmente, de forma aleatória, ou, então, com base
em algum tipo de prioridade. Mas isso pode consumir considerável tempo do processador,
ou seja, pode gerar um elevado overhead ao sistema.
Temos uma solução menos drástica que é a liberação de apenas alguns recursos
alocados aos processos para outros processos, até que o ciclo de espera termine.
Para esta solução ser realmente eficiente, é necessário que o sistema possa suspender
um processo, liberar seus recursos e, após a solução do problema, retornar à execução do
processo, sem perder o processamento já realizado. Esse mecanismo é conhecido como
rollback e, além do overhead gerado, é muito difícil de ser implementado, por ser bastante
dependente do aplicação que está sendo processada.
Todas as soluções para terminar com um deadlock são complicadas e sempre podem
gerar algum tipo de problema para o sistema, com isso chegamos à conclusão que a
tendência de se ter deadlock é cada vez mais freqüente e critico, na medida em que os
sistemas operacionais evoluem no sentido de implementar o paralelismo de forma intensiva
e permitir a alocação de um número ainda maior de recursos.

8. Gerência de Processador
Todo sistema multiprogramável possui um critério para determinar qual a ordem na
escolha dos processos para execução entre os vários que concorrem pela utilização do
processador.
O procedimento de seleção é uma das principias funções realizadas por um sistema
operacional, sendo conhecido como escalonamento (scheduling). A parte do código do
sistema operacional responsável pelo escalonamento é chamado de escalonador (scheduler).
Os principais objetivos basicamente são:
9 • Manter a UCP ocupada a maior parte do tempo;
9 • Balancear a utilização do processador entre os diversos processos;
9 • Maximizar o throughput do sistema;
9 • Oferecer tempos de resposta razoáveis para os usuários interativos.
Os objetivos devem ser atendidos de forma que o sistema trate todos os processos
igualmente, evitando, assim, que um processo fique indefinidamente esperando pela
utilização do processador.
Para atender alguns desses objetivos muitas vezes conflitantes, os sistemas operacionais
devem levar em consideração características dos processos, como:
9 • Tipo Batch;
9 • Interativo;
9 • CPU-bound;
9 • I/O-bound.
Sistema de tempo real ou tempo compartilhado também são aspectos fundamentais para
a implementação de uma política adequada de escalonamento.

8.1 Critérios de Escalonamento


Um algoritmo de escalonamento tem como principal função decidir qual dos
processos prontos para a execução deve ser alocado ã UCP. Cada sistema operacional
necessita de um algoritmo de escalonamento adequado a seu tipo de processamento, vamos
ver os principais critérios de escalonamento.

8.1.1 Utilização da UCP


Na maioria dos sistemas é desejável que o processador permaneça a maior parte do
seu tempo ocupado.

8.1.2 Throughput
Representa o número de processos (tarefas) executados em um determinado
intervalo de tempo.
A sua maximização é desejada na maioria dos sistemas.

8.1.3 Tempo de Turnaround


É o tempo que um processo leva desde sua admissão no sistema até o seu termino,
levando em consideração o tempo de espera para alocação de memória, espera na fila de
processos prontos para execução, processamento na UCP e operação de E/S.

8.1.4 Tempo de resposta


Em sistemas interativos, o tempo de resposta é o tempo decorrido do momento da
submissão de um pedido ao sistema até a primeira resposta produzida. Esse tempo não é o
tempo total utilizado no processamento de uma tarefa, e sim o tempo decorrido até que uma
resposta seja apresentada. Este tempo, geralmente, é limitado pela velocidade do
dispositivo de saída.
De uma maneira geral, qualquer algoritmo de escalonamento busca otimizar a
utilização da UCP e o throughput, tenta diminuir os tempos de turnaround e de resposta.
O Algoritmo de escalonamento não é o único responsável pelo tempo de execução
de um processo. Outros fatores, como o tempo de processamento e de espera em operações
de E/S, devem ser considerados no tempo total da execução. O escalonamento somente
afeta o tempo de espera dos processos na fila de pronto.

8.2 Escalonamento Não-preenptivo


Este escalonamento é aquele que usa o processamento Batch. Nesse tipo de
escalonamento, quando um processo (job) ganha o direito de utilizar a UCP, nenhum outro
processo pode lhe tirar esse recurso, vamos analisar alguns algoritmos de escalonamento
não-preemptivos.

8.2.1 Escalonamento First-In-First-Out (FIFO)


Neste escalonamento, o processo que chega primeiro (firist-in) é o primeiro a ser
selecionado para execução (first-out). Seu algoritmo de implementação é bastante simples,
sendo necessária apenas uma fila, onde os processos que passam para o estado de pronto
entram no seu final e são escalonados quando chegarem ao seu inicio.
O problema do escalonamento FIFO é a impossibilidade de se prever quando um
processo terá sua execução iniciada, já que isso varia em função do tempo de execução dos
demais processos que se encontram na sua frente. Outro problema é a possibilidade de
processos CPU-bound de menor importância prejudicam processos I/O-bound mais
prioritários.
O FIFO foi inicialmente implementado em sistemas batch, sendo ineficiente, se
aplicada da forma original em sistemas de tempo compartilhado. Hoje os sistemas de tempo
compartilhados usam o escalonamento FIFO com variações.
8.2.2. Escalonamento Shortest-Job-First (SJF)
Esse algoritmo de escalonamento associa cada processo (ou job) ao seu tempo de
execução.
Dessa forma, quando o processador está livre, o processo em estado de pronto que
precisar de menos tempo de UCP para terminar seu processamento é selecionado para
execução (shortest-job-first).
O escalonamento SJF favorece os processos que executam programas menores,
além de reduzir o tempo médio de espera em relação ao FIFO. O problema em relação a
esse algoritmo é determinar, exatamente, quanto tempo de UCP cada processo necessita
para terminar seu processamento. Esse tempo nem sempre é determinado de forma precisa.
Em ambientes de produção, onde os programas executam freqüentemente o mesmo tipo de
processo, é possível estimar o tempo de execução, mas em ambientes de desenvolvimento
isso se torna difícil.
Tanto o SJF quanto o FIFO não são algoritmo de escalonamentos aplicados a
sistema de tempo compartilhado, onde um tempo de resposta razoável deve ser garantido ao
usuário interativo.
8.2.3 Escalonamento Cooperativo
Nesse escalonamento alguma política não-preemptiva deve ser adotada. A partir do
momento que um processo está em execução, este voluntariamente libera o processador,
retornando para a fila de pronto.
Este tipo de escalonamento permite a implementação de sistemas
multiprogramaveis com uma melhor distribuição do uso do processador entre os processos.
Sua principal característica está no fato de a liberação do processador ser uma tarefa
realizada exclusivamente pelo processo em execução, que de uma maneira cooperativa
libera a UCP para um outro processo.
Neste escalonamento não existe nenhuma intervenção do sistema operacional na
execução do processo. Isto pode ocasionar sérios problemas na medida em que um
programa pode não liberar o processador ou um programa mal escrito pode entrar em
looping, monopolizando desta forma a UCP.

8.3 Escalonamento Preemptivo


Ele é preempitivo quando o sistema pode interromper um processo em execução
para que outro processo utilize o processador. Em sistema que não implementam
preempção, um processo pode utilizar o processador enquanto for necessário.
Ele permite que o sistema dê atenção imediata a processos mais prioritários, como
no caso de sistemas de tempo real, além de proporcionar melhores tempos de resposta em
sistemas de tempo compartilhado. Outro beneficio decorrente deste tipo de escalonamento é
o compartilhamento do processador de uma maneira mais uniforme entre os processos.
A troca de um processo por outro na UCP (mudança de contexto), causada pela
preempção, gera um overhead ao sistema. Para isso não se tornar critico, o sistema deve
estabelecer corretamente os critérios de preempção, vamos ver alguns dos principais
algoritmos de escalonamento preemptivos.

8.3.1 Escalonamento Circular


Este escalonamento é implementado através de um algoritmo projetado
especialmente para sistemas de tempo compartilhado, também chamado de round robin. Ele
é semelhante ao FIFO, porém, quando um processo passa para o estado de execução, existe
um tempo limite para sua execução de forma continua. E se esse tempo (time-slice) expirar
sem que antes a UCP tenho sido liberada pelo processo ele volta ao estado de pronto dando
vez a outro processo e esse mecanismo é definido como preempção por tempo.
A fila de processos em estado de pronto é tratada como uma fila circular. O
escalonamento é realizado, alocando a UCP para cada processo da fila no intervalo de
tempo determinado pelo quantum.
Em geral, o valor do quantum de tempo está entre 100 e 300 ms.
Através do escalonamento circular nenhum processo poderá monopolizar a UCP,
sendo o tempo máximo alocado continuamente para um determinado processo igual ao
quantum definido pelo sistema. Em tempo compartilhado esse algoritmo é bastante
adequado, devido ter vários usuários utilizando o sistema concorrentemente.

8.3.2 Escalonamento por Prioridades


Este tipo de escalonamento consegue melhorar a distribuição do tempo de UCP em
relação aos escalonamentos não-preemptivos, porém, ainda não consegue implementar um
compartilhamento eqüitativo entre os diversos tipos de processos. Isso acontece em razão
de o escalonamento circular tratar todos os processos de uma maneira igual, o que nem
sempre é desejável.

Para solucionar esse problema, os processos I/O-bound devem levar alguma


vantagem no escalonamento, a fim de compensar o excessivo tempo gasto no estado de
espera. Como alguns processos são tratados de maneira diferente dos outros, devemos
associar a cada um deles uma prioridade de execução. Neste caso quando chegar um
processo com prioridade superior o sistema deverá interromper o processo corrente e
coloca-lo em estado de pronto e selecionar o de maior prioridade para ser executado. Esse
mecanismo é definido como preempção por prioridade.
A preempção por prioridade é implementada mediante um clock, que interrompe o
processador em determinados intervalos de tempo, para que a rotina de escalonamento
reavalie prioridades e, possivelmente, escalone outro processo.
Todos os sistemas de tempo compartilhados implementam algum esquema de
prioridade, de forma a dar maior importância a um processo no momento do
escalonamento. A prioridade é uma característica do contexto de software podendo ser
estática ou dinâmica.
A prioridade é estática quando não é modificada durante a existência do processo.
Apesar de ser simples a implementação pode ocasionar tempo de resposta elevado.
A prioridade é dinâmica quando ela puder ser ajustada de acordo com o tipo de
processamento realizado pelo processo e/ou a carga do sistema. Como todo processo, ao
sair do estado de espera, recebe um acréscimo à sua prioridade, os processos I/O-bound
terão mais chance de ser escalonados e, assim, compensar o tempo que passam no estado de
espera.

8.3.3 Escalonamento por Múltiplas Filas


Uma boa política seria classificar os processos em função do tipo de processamento
realizado e aplicar a cada grupo mecanismos de escalonamento distintos, isso porque os
diversos processos do sistema possuem características de processamento diferentes.
Assim sendo o escalonamento por múltiplas filas (mult-level queues) implementa
diversas filas de processo no estado de pronto, onde cada processo é associado
exclusivamente a uma deles.
Assim os processos devem ser classificados, previamente, em função do tipo em
ralação às outras. O sistema só pode escalonar processos de uma fila se todas as outras de
prioridade maior estiverem vazias.
Os processos de usuários interativos devem estar em uma fila de prioridade
intermediária, implementando, por exemplo, o escalonamento circular. O mesmo
mecanismo de escalonamento pode ser utilizado na fila de processos batch, com a diferença
de que esta fila deverá possuir uma prioridade mais baixa.

8.3.3.1 Escalonamento por Múltiplas Filas com Realimentação


Esse escalonamento vem para melhorar os demais, por poder ajustar dinamicamente
seus tipos de escalonamentos. O multi-level-feedback queues, implementa diversas filas,
onde cada qual tem associada uma prioridade de execução, porém os processos não
permanecem em uma mesma fila até o término do processamento. Ele tenta identificar
dinamicamente o comportamento de cada processo, ajustando assim prioridades de
execução e mecanismos de escalonamento.
Com isso é permitido que os processos sejam redirecionados entre as filas do
sistema, fazendo com que o sistema operacional implemente um mecanismo de ajuste
dinâmico, denominado mecanismo adaptativo, que tem como objetivo ajustar os processos
em função do comportamento do sistema. Os processos não são previamente associados às
filas de pronto, e sim direcionados pelo sistema entre as diversas filas com base no seu
comportamento.
O escalonamento por múltiplas filas com realimentação é um algoritmo de
escalonamento generalista, podendo ser implementado em qualquer tipo de sistema
operacional. Seu maior problema é que, por sua complexidade, pode gerar um grande
overhead ao sistema, o que mesmo assim, pode justificar sua implementação.

8.3.4 Escalonamento de Sistemas de Tempo Real


São freqüentemente utilizados em aplicações de controle de processos. Sistemas que
controlam industrias, de controle de tráfego aéreo entre outros são exemplos deste tipo de
sistema.
Nos sistemas operacionais de tempo real, o fator tempo é crítico. Diferentemente
dos sistemas de tempo compartilhado, onde um pequeno tempo de resposta é desejado,
porém não obrigatório todo processamento em tempo real deve ser realizado dentro de
limites rígidos de tempo ou, caso contrário, todo o sistema pode ficar comprometido.
No escalonamento para este tipo de sistema não existe o conceito de quantum ou
time-slice. O escalonamento é realizado unicamente com base no esquema de prioridades,
Para cada processo é atribuída uma prioridade associada a sua importância dentro do
sistema. Esta prioridade deve ser estática, não devendo ser alterada no decorrer do
processamento.
O escalonamento de tempo real deve ser empregado na solução de aplicações onde
existam graus de exigência na execução de suas tarefas. Quanto maior a importância de
uma tarefa maior sua prioridade de execução em relação às demais. Dessa forma, é possível
implementar níveis de prioridade entre as tarefas da aplicação, conforme a necessidade na
solução de cada problema.

8.3.5 Escalonamento com Múltiplos Processadores


Neste escalonamento a abordagem é diferente quando tratamos de sistemas de
escalonamento fracamente ou fortemente acoplados.
Como sabemos nos Sistemas. Fracamente A., cada processador trabalha em sua
máquina, tendo memória, sistema operacional, algoritmo de escalonamento e sua própria
fila de processos prontos para execução.
Nos sistemas fortemente acoplados é possível implementar uma única fila de pronto
para todos os processadores. Todos os processos estão presentes nesta única fila e são
escalonados no primeiro processador disponível. Para está solução a exclusão mútua é
muito importante e tem que ser implantada. No caso de mais de um processador se tornar
disponível no mesmo instante, não pode haver possibilidade de um mesmo processo ser
escalonado por dois processadores diferentes. A exclusão mútua pode ser adquirida através
de mecanismos como semáforo e monitores.
Note que, como a memória é única para todos os processadores, contendo assim
todos os programas, não faz diferença em qual processador a execução ocorrerá.

Você também pode gostar